diff --git a/python_part/ohos.build b/python_part/ohos.build new file mode 100755 index 0000000000000000000000000000000000000000..0f08130f2c7e74b4f37f890c5ae2eadb21aa785b --- /dev/null +++ b/python_part/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_part/python/BUILD.gn b/python_part/python/BUILD.gn new file mode 100755 index 0000000000000000000000000000000000000000..0cf6a996333280478b94413e660da01e2755c3e3 --- /dev/null +++ b/python_part/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_part/python/Modules/README b/python_part/python/Modules/README new file mode 100755 index 0000000000000000000000000000000000000000..9b79f538892f174cd43a736d3e9a26faa7cda92f --- /dev/null +++ b/python_part/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_part/python/Modules/Setup b/python_part/python/Modules/Setup new file mode 100755 index 0000000000000000000000000000000000000000..983fa014ecb242bf8716a7ff997f56aaee6e913c --- /dev/null +++ b/python_part/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_part/python/Modules/Setup.local b/python_part/python/Modules/Setup.local new file mode 100755 index 0000000000000000000000000000000000000000..ca2983e22e8602b865d2d7e6283c8f11e7e8415e --- /dev/null +++ b/python_part/python/Modules/Setup.local @@ -0,0 +1 @@ +# Edit this file for local setup changes diff --git a/python_part/python/Modules/_abc.c b/python_part/python/Modules/_abc.c new file mode 100755 index 0000000000000000000000000000000000000000..de938dd0d7d5252830ede85c7ce948cbaeb3d353 --- /dev/null +++ b/python_part/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_part/python/Modules/_asynciomodule.c b/python_part/python/Modules/_asynciomodule.c new file mode 100755 index 0000000000000000000000000000000000000000..4ed2af5598029cc49946eaeb1383f80cb32af911 --- /dev/null +++ b/python_part/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_part/python/Modules/_bisectmodule.c b/python_part/python/Modules/_bisectmodule.c new file mode 100755 index 0000000000000000000000000000000000000000..461a11f5099db323db2db4117843e982090d7ba7 --- /dev/null +++ b/python_part/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_part/python/Modules/_blake2/blake2b2s.py b/python_part/python/Modules/_blake2/blake2b2s.py new file mode 100755 index 0000000000000000000000000000000000000000..01cf26521b37796a056eb44cf82bd2c502bb6035 --- /dev/null +++ b/python_part/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_part/python/Modules/_blake2/blake2b_impl.c b/python_part/python/Modules/_blake2/blake2b_impl.c new file mode 100755 index 0000000000000000000000000000000000000000..edab31ea222ab82fdff89a8bf48fa037f3836641 --- /dev/null +++ b/python_part/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_part/python/Modules/_blake2/blake2module.c b/python_part/python/Modules/_blake2/blake2module.c new file mode 100755 index 0000000000000000000000000000000000000000..e2a3d420d4eb8ef845df04943f43ba85e18b61db --- /dev/null +++ b/python_part/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_part/python/Modules/_blake2/blake2ns.h b/python_part/python/Modules/_blake2/blake2ns.h new file mode 100755 index 0000000000000000000000000000000000000000..53bce8e0fcd066ed42c58f540e34d855991a4b59 --- /dev/null +++ b/python_part/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_part/python/Modules/_blake2/blake2s_impl.c b/python_part/python/Modules/_blake2/blake2s_impl.c new file mode 100755 index 0000000000000000000000000000000000000000..ef2f7e1980ff30db926a283bcafb61a20f2f01bc --- /dev/null +++ b/python_part/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_part/python/Modules/_blake2/clinic/blake2b_impl.c.h b/python_part/python/Modules/_blake2/clinic/blake2b_impl.c.h new file mode 100755 index 0000000000000000000000000000000000000000..cd329c07c99981942dcaa570a1a5db2769676b2e --- /dev/null +++ b/python_part/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_part/python/Modules/_blake2/clinic/blake2s_impl.c.h b/python_part/python/Modules/_blake2/clinic/blake2s_impl.c.h new file mode 100755 index 0000000000000000000000000000000000000000..560bd68160b016645a70cf1cfbd75ff6576744a8 --- /dev/null +++ b/python_part/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_part/python/Modules/_blake2/impl/blake2-config.h b/python_part/python/Modules/_blake2/impl/blake2-config.h new file mode 100755 index 0000000000000000000000000000000000000000..f5dd6faa9e6867f743a29c99b4f94b86322a5d2d --- /dev/null +++ b/python_part/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_part/python/Modules/_blake2/impl/blake2-dispatch.c b/python_part/python/Modules/_blake2/impl/blake2-dispatch.c new file mode 100755 index 0000000000000000000000000000000000000000..96bb3408bb1e2050562bf3746071d89c3d104d97 --- /dev/null +++ b/python_part/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_part/python/Modules/_blake2/impl/blake2-impl.h b/python_part/python/Modules/_blake2/impl/blake2-impl.h new file mode 100755 index 0000000000000000000000000000000000000000..9d2fbb72fc1c0361c63bd3c05e580771501ffbb3 --- /dev/null +++ b/python_part/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_part/python/Modules/_blake2/impl/blake2-kat.h b/python_part/python/Modules/_blake2/impl/blake2-kat.h new file mode 100755 index 0000000000000000000000000000000000000000..3d2072763aa935c22fc07073311a3c4fc5e0e557 --- /dev/null +++ b/python_part/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_part/python/Modules/_blake2/impl/blake2.h b/python_part/python/Modules/_blake2/impl/blake2.h new file mode 100755 index 0000000000000000000000000000000000000000..a08d82efefe09ff8833932de3d13d79d55f9b558 --- /dev/null +++ b/python_part/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_part/python/Modules/_blake2/impl/blake2b-load-sse2.h b/python_part/python/Modules/_blake2/impl/blake2b-load-sse2.h new file mode 100755 index 0000000000000000000000000000000000000000..1ba153c87d7352bd7b2d60c55f06dc6b72cf2ab7 --- /dev/null +++ b/python_part/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_part/python/Modules/_blake2/impl/blake2b-load-sse41.h b/python_part/python/Modules/_blake2/impl/blake2b-load-sse41.h new file mode 100755 index 0000000000000000000000000000000000000000..f6c1bc8393f167df6974a57143802b01e7b9e981 --- /dev/null +++ b/python_part/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_part/python/Modules/_blake2/impl/blake2b-ref.c b/python_part/python/Modules/_blake2/impl/blake2b-ref.c new file mode 100755 index 0000000000000000000000000000000000000000..e58c43659d9cc8f81ff93bdc68d2c2de355ae8ef --- /dev/null +++ b/python_part/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_part/python/Modules/_blake2/impl/blake2b-round.h b/python_part/python/Modules/_blake2/impl/blake2b-round.h new file mode 100755 index 0000000000000000000000000000000000000000..cebc22550da4cd35890d8e04284b63f67400e35e --- /dev/null +++ b/python_part/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_part/python/Modules/_blake2/impl/blake2b-test.c b/python_part/python/Modules/_blake2/impl/blake2b-test.c new file mode 100755 index 0000000000000000000000000000000000000000..9310a273a517281ad198befbe0ee4efe0c1bc15e --- /dev/null +++ b/python_part/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_part/python/Modules/_blake2/impl/blake2b.c b/python_part/python/Modules/_blake2/impl/blake2b.c new file mode 100755 index 0000000000000000000000000000000000000000..c1068e8640546a1bcb794c009214fa7e99bab12f --- /dev/null +++ b/python_part/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_part/python/Modules/_blake2/impl/blake2bp-test.c b/python_part/python/Modules/_blake2/impl/blake2bp-test.c new file mode 100755 index 0000000000000000000000000000000000000000..849666cc1d5ecc60c5422af2d8a4738c6d060d31 --- /dev/null +++ b/python_part/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_part/python/Modules/_blake2/impl/blake2bp.c b/python_part/python/Modules/_blake2/impl/blake2bp.c new file mode 100755 index 0000000000000000000000000000000000000000..45221611710108d6b49ec8b86d672df8937e43ab --- /dev/null +++ b/python_part/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_part/python/Modules/_blake2/impl/blake2s-load-sse2.h b/python_part/python/Modules/_blake2/impl/blake2s-load-sse2.h new file mode 100755 index 0000000000000000000000000000000000000000..b24483cf931c1f031f37e2bdb9b5a58416267217 --- /dev/null +++ b/python_part/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_part/python/Modules/_blake2/impl/blake2s-load-sse41.h b/python_part/python/Modules/_blake2/impl/blake2s-load-sse41.h new file mode 100755 index 0000000000000000000000000000000000000000..3ac12eb6f5d08298ab8db789eb7bab93ac39675d --- /dev/null +++ b/python_part/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_part/python/Modules/_blake2/impl/blake2s-load-xop.h b/python_part/python/Modules/_blake2/impl/blake2s-load-xop.h new file mode 100755 index 0000000000000000000000000000000000000000..ac591a77d191a7e85d77ce92096e549b36ba55b6 --- /dev/null +++ b/python_part/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_part/python/Modules/_blake2/impl/blake2s-ref.c b/python_part/python/Modules/_blake2/impl/blake2s-ref.c new file mode 100755 index 0000000000000000000000000000000000000000..ab86cc1b34e67d7c41aca82ebba7fc2b53c81d35 --- /dev/null +++ b/python_part/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_part/python/Modules/_blake2/impl/blake2s-round.h b/python_part/python/Modules/_blake2/impl/blake2s-round.h new file mode 100755 index 0000000000000000000000000000000000000000..1e2f2b7f59bd6c9c354306a1046d793c77f5667a --- /dev/null +++ b/python_part/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_part/python/Modules/_blake2/impl/blake2s-test.c b/python_part/python/Modules/_blake2/impl/blake2s-test.c new file mode 100755 index 0000000000000000000000000000000000000000..5c3f1f189d79cda9540fbfd1052ff40ebf51f82b --- /dev/null +++ b/python_part/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_part/python/Modules/_blake2/impl/blake2s.c b/python_part/python/Modules/_blake2/impl/blake2s.c new file mode 100755 index 0000000000000000000000000000000000000000..47514685b8f30b849895d8ffa9251a2bc48c3585 --- /dev/null +++ b/python_part/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_part/python/Modules/_blake2/impl/blake2sp-test.c b/python_part/python/Modules/_blake2/impl/blake2sp-test.c new file mode 100755 index 0000000000000000000000000000000000000000..621e3506cfbdf7fe2ac040ba34afeec5cd494de0 --- /dev/null +++ b/python_part/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_part/python/Modules/_blake2/impl/blake2sp.c b/python_part/python/Modules/_blake2/impl/blake2sp.c new file mode 100755 index 0000000000000000000000000000000000000000..2f32bf3a226bf67bab1407dfeaf35c8be6440e79 --- /dev/null +++ b/python_part/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_part/python/Modules/_bz2module.c b/python_part/python/Modules/_bz2module.c new file mode 100755 index 0000000000000000000000000000000000000000..b8a10ba9683e5de9dc7c63cd18d3f4b771ae7be6 --- /dev/null +++ b/python_part/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_part/python/Modules/_codecsmodule.c b/python_part/python/Modules/_codecsmodule.c new file mode 100755 index 0000000000000000000000000000000000000000..a8ffb699557abf84216bf996bd996bdaf0129006 --- /dev/null +++ b/python_part/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_part/python/Modules/_collectionsmodule.c b/python_part/python/Modules/_collectionsmodule.c new file mode 100755 index 0000000000000000000000000000000000000000..cc2b90eaa283ea3f704e1a3f593dfcb32ffba642 --- /dev/null +++ b/python_part/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_part/python/Modules/_contextvarsmodule.c b/python_part/python/Modules/_contextvarsmodule.c new file mode 100755 index 0000000000000000000000000000000000000000..1abcdbfa921c272bab371f1818dc7fd6ca1779c4 --- /dev/null +++ b/python_part/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_part/python/Modules/_cryptmodule.c b/python_part/python/Modules/_cryptmodule.c new file mode 100755 index 0000000000000000000000000000000000000000..5d03f45f643615315ddaf20758c0dcd659e6a6db --- /dev/null +++ b/python_part/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_part/python/Modules/_csv.c b/python_part/python/Modules/_csv.c new file mode 100755 index 0000000000000000000000000000000000000000..069ec9602cc9ce059c38bc042428405c12ba9cd9 --- /dev/null +++ b/python_part/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_part/python/Modules/_ctypes/_ctypes.c b/python_part/python/Modules/_ctypes/_ctypes.c new file mode 100755 index 0000000000000000000000000000000000000000..b10b86725ff171da479cb4bbba84ef08f65ca30e --- /dev/null +++ b/python_part/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_part/python/Modules/_ctypes/_ctypes_test.c b/python_part/python/Modules/_ctypes/_ctypes_test.c new file mode 100755 index 0000000000000000000000000000000000000000..33922082ab11a85ae8a2f012767309bee3aef2e3 --- /dev/null +++ b/python_part/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_part/python/Modules/_ctypes/_ctypes_test.h b/python_part/python/Modules/_ctypes/_ctypes_test.h new file mode 100755 index 0000000000000000000000000000000000000000..060d4d69b699a2122ae101139d921656f2f49d61 --- /dev/null +++ b/python_part/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_part/python/Modules/_ctypes/callbacks.c b/python_part/python/Modules/_ctypes/callbacks.c new file mode 100755 index 0000000000000000000000000000000000000000..b826ee3c0a49f77af683105674d2511b7fcf19ad --- /dev/null +++ b/python_part/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_part/python/Modules/_ctypes/callproc.c b/python_part/python/Modules/_ctypes/callproc.c new file mode 100755 index 0000000000000000000000000000000000000000..e326cd84f8c49e5e6a17f43e971fc6f66e805d5f --- /dev/null +++ b/python_part/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_part/python/Modules/_ctypes/cfield.c b/python_part/python/Modules/_ctypes/cfield.c new file mode 100755 index 0000000000000000000000000000000000000000..0b12a448693b53368621f75b26829cb5b4f82785 --- /dev/null +++ b/python_part/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_part/python/Modules/_ctypes/ctypes.h b/python_part/python/Modules/_ctypes/ctypes.h new file mode 100755 index 0000000000000000000000000000000000000000..0bed85e318261f78baf3e752beca92cd19d2dfbb --- /dev/null +++ b/python_part/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_part/python/Modules/_ctypes/ctypes_dlfcn.h b/python_part/python/Modules/_ctypes/ctypes_dlfcn.h new file mode 100755 index 0000000000000000000000000000000000000000..54cdde9a4fdb02450bbc4d7b81b2dfcf778772c9 --- /dev/null +++ b/python_part/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_part/python/Modules/_ctypes/darwin/LICENSE b/python_part/python/Modules/_ctypes/darwin/LICENSE new file mode 100755 index 0000000000000000000000000000000000000000..786fb50258eb85fc25bc797105552c27878401ff --- /dev/null +++ b/python_part/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_part/python/Modules/_ctypes/darwin/README b/python_part/python/Modules/_ctypes/darwin/README new file mode 100755 index 0000000000000000000000000000000000000000..4d63f3dfa5ebc7b035b7e82595ab962c5874a34e --- /dev/null +++ b/python_part/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_part/python/Modules/_ctypes/darwin/README.ctypes b/python_part/python/Modules/_ctypes/darwin/README.ctypes new file mode 100755 index 0000000000000000000000000000000000000000..8520b01f49da1de444f9c3dfb35c5828205554d3 --- /dev/null +++ b/python_part/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_part/python/Modules/_ctypes/darwin/dlfcn.h b/python_part/python/Modules/_ctypes/darwin/dlfcn.h new file mode 100755 index 0000000000000000000000000000000000000000..a2afc3eeb84794bd27ce338c839d731484c20b7c --- /dev/null +++ b/python_part/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_part/python/Modules/_ctypes/darwin/dlfcn_simple.c b/python_part/python/Modules/_ctypes/darwin/dlfcn_simple.c new file mode 100755 index 0000000000000000000000000000000000000000..2b293bb8695bce9e9e7dea1ddced2aabc8726bea --- /dev/null +++ b/python_part/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_part/python/Modules/_ctypes/libffi_osx/LICENSE b/python_part/python/Modules/_ctypes/libffi_osx/LICENSE new file mode 100755 index 0000000000000000000000000000000000000000..f591795152d66fc43cad5e55b4adbf66c73b37a2 --- /dev/null +++ b/python_part/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_part/python/Modules/_ctypes/libffi_osx/README b/python_part/python/Modules/_ctypes/libffi_osx/README new file mode 100755 index 0000000000000000000000000000000000000000..69e46cbf8a420fa5e63796cad97a938e01ab8a73 --- /dev/null +++ b/python_part/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_part/python/Modules/_ctypes/libffi_osx/README.pyobjc b/python_part/python/Modules/_ctypes/libffi_osx/README.pyobjc new file mode 100755 index 0000000000000000000000000000000000000000..405d85fed2def9154169e16b6e2c93d1509b08f5 --- /dev/null +++ b/python_part/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_part/python/Modules/_ctypes/libffi_osx/ffi.c b/python_part/python/Modules/_ctypes/libffi_osx/ffi.c new file mode 100755 index 0000000000000000000000000000000000000000..1776b795e2f83d8c997eabbde8348a5b3433835d --- /dev/null +++ b/python_part/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_part/python/Modules/_ctypes/libffi_osx/include/ffi.h b/python_part/python/Modules/_ctypes/libffi_osx/include/ffi.h new file mode 100755 index 0000000000000000000000000000000000000000..c104a5c89350b657df7703f8a70c062a31d64561 --- /dev/null +++ b/python_part/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_part/python/Modules/_ctypes/libffi_osx/include/ffi_common.h b/python_part/python/Modules/_ctypes/libffi_osx/include/ffi_common.h new file mode 100755 index 0000000000000000000000000000000000000000..685a3580f4fe05e8e40178da03b3df0066fa804d --- /dev/null +++ b/python_part/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_part/python/Modules/_ctypes/libffi_osx/include/fficonfig.h b/python_part/python/Modules/_ctypes/libffi_osx/include/fficonfig.h new file mode 100755 index 0000000000000000000000000000000000000000..217249071dcf48672199140a17805c387d5ee05a --- /dev/null +++ b/python_part/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_part/python/Modules/_ctypes/libffi_osx/include/ffitarget.h b/python_part/python/Modules/_ctypes/libffi_osx/include/ffitarget.h new file mode 100755 index 0000000000000000000000000000000000000000..faaa30de6f6f26afd183c08fee59cd7d6a5061a2 --- /dev/null +++ b/python_part/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_part/python/Modules/_ctypes/libffi_osx/include/ppc-ffitarget.h b/python_part/python/Modules/_ctypes/libffi_osx/include/ppc-ffitarget.h new file mode 100755 index 0000000000000000000000000000000000000000..2318421990569c684a01d87dba872686d81c524c --- /dev/null +++ b/python_part/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_part/python/Modules/_ctypes/libffi_osx/include/x86-ffitarget.h b/python_part/python/Modules/_ctypes/libffi_osx/include/x86-ffitarget.h new file mode 100755 index 0000000000000000000000000000000000000000..55c2b6c50cd90ceefee0fbd707e4d6ff73718d9b --- /dev/null +++ b/python_part/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_part/python/Modules/_ctypes/libffi_osx/powerpc/ppc-darwin.S b/python_part/python/Modules/_ctypes/libffi_osx/powerpc/ppc-darwin.S new file mode 100755 index 0000000000000000000000000000000000000000..f143dbd28c3de735793e14c83c1268e4d3040208 --- /dev/null +++ b/python_part/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_part/python/Modules/_ctypes/libffi_osx/powerpc/ppc-darwin.h b/python_part/python/Modules/_ctypes/libffi_osx/powerpc/ppc-darwin.h new file mode 100755 index 0000000000000000000000000000000000000000..cf4bd50f93c35b1f3a18c1919c55b5af3bb5b419 --- /dev/null +++ b/python_part/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_part/python/Modules/_ctypes/libffi_osx/powerpc/ppc-darwin_closure.S b/python_part/python/Modules/_ctypes/libffi_osx/powerpc/ppc-darwin_closure.S new file mode 100755 index 0000000000000000000000000000000000000000..c3d30c25254cd214206d60c5b4935b4b748e5bb6 --- /dev/null +++ b/python_part/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_part/python/Modules/_ctypes/libffi_osx/powerpc/ppc-ffi_darwin.c b/python_part/python/Modules/_ctypes/libffi_osx/powerpc/ppc-ffi_darwin.c new file mode 100755 index 0000000000000000000000000000000000000000..8953d5fda35818334123c592a031f4fad773a00d --- /dev/null +++ b/python_part/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_part/python/Modules/_ctypes/libffi_osx/powerpc/ppc64-darwin_closure.S b/python_part/python/Modules/_ctypes/libffi_osx/powerpc/ppc64-darwin_closure.S new file mode 100755 index 0000000000000000000000000000000000000000..7162fa1dda654db4de8cee2c0711255ae85b6a8b --- /dev/null +++ b/python_part/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_part/python/Modules/_ctypes/libffi_osx/types.c b/python_part/python/Modules/_ctypes/libffi_osx/types.c new file mode 100755 index 0000000000000000000000000000000000000000..44806aeeb75d37e47340a75e1e90db2f543fd7f9 --- /dev/null +++ b/python_part/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_part/python/Modules/_ctypes/libffi_osx/x86/darwin64.S b/python_part/python/Modules/_ctypes/libffi_osx/x86/darwin64.S new file mode 100755 index 0000000000000000000000000000000000000000..1286d33f83e0acac5482c1c1fed6b0d275e29233 --- /dev/null +++ b/python_part/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_part/python/Modules/_ctypes/libffi_osx/x86/x86-darwin.S b/python_part/python/Modules/_ctypes/libffi_osx/x86/x86-darwin.S new file mode 100755 index 0000000000000000000000000000000000000000..925a84131661e92f75e1e40a395f66ef8fc28b4d --- /dev/null +++ b/python_part/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_part/python/Modules/_ctypes/libffi_osx/x86/x86-ffi64.c b/python_part/python/Modules/_ctypes/libffi_osx/x86/x86-ffi64.c new file mode 100755 index 0000000000000000000000000000000000000000..f2610c16c78379fd43f2b2b308ede6701e2afd9d --- /dev/null +++ b/python_part/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_part/python/Modules/_ctypes/libffi_osx/x86/x86-ffi_darwin.c b/python_part/python/Modules/_ctypes/libffi_osx/x86/x86-ffi_darwin.c new file mode 100755 index 0000000000000000000000000000000000000000..706ea0f51206dc61724d3031102cd9bc13bface6 --- /dev/null +++ b/python_part/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_part/python/Modules/_ctypes/malloc_closure.c b/python_part/python/Modules/_ctypes/malloc_closure.c new file mode 100755 index 0000000000000000000000000000000000000000..788bae6a96c7f4a8558f8ef3f34c01c747e659fd --- /dev/null +++ b/python_part/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_part/python/Modules/_ctypes/stgdict.c b/python_part/python/Modules/_ctypes/stgdict.c new file mode 100755 index 0000000000000000000000000000000000000000..1d45ade5efd9037c194f0f4bfacd22d2c179ee30 --- /dev/null +++ b/python_part/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_part/python/Modules/_curses_panel.c b/python_part/python/Modules/_curses_panel.c new file mode 100755 index 0000000000000000000000000000000000000000..0c17e481dc81a3941754410d445b5888e0680237 --- /dev/null +++ b/python_part/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_part/python/Modules/_cursesmodule.c b/python_part/python/Modules/_cursesmodule.c new file mode 100755 index 0000000000000000000000000000000000000000..ea1d5a7dde39a28e940d96f82799dcffa375ceb3 --- /dev/null +++ b/python_part/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_part/python/Modules/_datetimemodule.c b/python_part/python/Modules/_datetimemodule.c new file mode 100755 index 0000000000000000000000000000000000000000..d428210542d41b115ca361afff0822aca3cf476d --- /dev/null +++ b/python_part/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_part/python/Modules/_dbmmodule.c b/python_part/python/Modules/_dbmmodule.c new file mode 100755 index 0000000000000000000000000000000000000000..d46c3c60644696102018850c8431afe93ba2a877 --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/README.txt b/python_part/python/Modules/_decimal/README.txt new file mode 100755 index 0000000000000000000000000000000000000000..7eae0f88f2842806ea24af475d622b705d104fc7 --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/_decimal.c b/python_part/python/Modules/_decimal/_decimal.c new file mode 100755 index 0000000000000000000000000000000000000000..eb1f1a01feeca8374b1e67adb045e8b1953e86f1 --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/docstrings.h b/python_part/python/Modules/_decimal/docstrings.h new file mode 100755 index 0000000000000000000000000000000000000000..f7fd6e795299845f44f43b8479f39a00d282fde2 --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/libmpdec/README.txt b/python_part/python/Modules/_decimal/libmpdec/README.txt new file mode 100755 index 0000000000000000000000000000000000000000..96b72232d2ad7c6df5c2b3c6717f28d396c16cf9 --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/libmpdec/basearith.c b/python_part/python/Modules/_decimal/libmpdec/basearith.c new file mode 100755 index 0000000000000000000000000000000000000000..dfe1523927a4078c5f6d9d2ed15a06dffa44d661 --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/libmpdec/basearith.h b/python_part/python/Modules/_decimal/libmpdec/basearith.h new file mode 100755 index 0000000000000000000000000000000000000000..976358a110ecf3e7580ae4bc682057bc0aa4ee8a --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/libmpdec/bits.h b/python_part/python/Modules/_decimal/libmpdec/bits.h new file mode 100755 index 0000000000000000000000000000000000000000..b5eaa24976ae51bb7afe4fa9453254735832ace2 --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/libmpdec/constants.c b/python_part/python/Modules/_decimal/libmpdec/constants.c new file mode 100755 index 0000000000000000000000000000000000000000..2c2d5ea4810353935d2adcb7a74d204f2d6a20c3 --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/libmpdec/constants.h b/python_part/python/Modules/_decimal/libmpdec/constants.h new file mode 100755 index 0000000000000000000000000000000000000000..c0febfc8772d7e2c4b0c650cc1cbab0eb13bcd9e --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/libmpdec/context.c b/python_part/python/Modules/_decimal/libmpdec/context.c new file mode 100755 index 0000000000000000000000000000000000000000..24c7b890c1d9895f1a92b68c65561bd0f38b85a4 --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/libmpdec/convolute.c b/python_part/python/Modules/_decimal/libmpdec/convolute.c new file mode 100755 index 0000000000000000000000000000000000000000..4c62e8bd3abd808a5cd4f88b0a45b425b9764cbd --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/libmpdec/convolute.h b/python_part/python/Modules/_decimal/libmpdec/convolute.h new file mode 100755 index 0000000000000000000000000000000000000000..f30a177a684067785f0bca011c3898fd6df8136c --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/libmpdec/crt.c b/python_part/python/Modules/_decimal/libmpdec/crt.c new file mode 100755 index 0000000000000000000000000000000000000000..4a1e80a232284fb85b7b6973a18aed44cc03d412 --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/libmpdec/crt.h b/python_part/python/Modules/_decimal/libmpdec/crt.h new file mode 100755 index 0000000000000000000000000000000000000000..f61e77293632e16a7dade2e89697d7e8f9ecded0 --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/libmpdec/difradix2.c b/python_part/python/Modules/_decimal/libmpdec/difradix2.c new file mode 100755 index 0000000000000000000000000000000000000000..06e5ab5e222ee099be9a7f858ba51284cc834d30 --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/libmpdec/difradix2.h b/python_part/python/Modules/_decimal/libmpdec/difradix2.h new file mode 100755 index 0000000000000000000000000000000000000000..5e22bcf324fac78645235528f4638093231731a2 --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/libmpdec/fnt.c b/python_part/python/Modules/_decimal/libmpdec/fnt.c new file mode 100755 index 0000000000000000000000000000000000000000..7e924c85242b08df5d55d0fbe993427d383067a6 --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/libmpdec/fnt.h b/python_part/python/Modules/_decimal/libmpdec/fnt.h new file mode 100755 index 0000000000000000000000000000000000000000..fa2154a798d453bdc42c58411c5d17b203212b2d --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/libmpdec/fourstep.c b/python_part/python/Modules/_decimal/libmpdec/fourstep.c new file mode 100755 index 0000000000000000000000000000000000000000..21d3e7485df4dabf890f62926afbb3c1ef396af7 --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/libmpdec/io.c b/python_part/python/Modules/_decimal/libmpdec/io.c new file mode 100755 index 0000000000000000000000000000000000000000..f45e558f1a9573448a9e4b9d73505cca7bb4d998 --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/libmpdec/io.h b/python_part/python/Modules/_decimal/libmpdec/io.h new file mode 100755 index 0000000000000000000000000000000000000000..de5486a00ca56f14b8bf840adf40d15e6ab9f904 --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/libmpdec/literature/REFERENCES.txt b/python_part/python/Modules/_decimal/libmpdec/literature/REFERENCES.txt new file mode 100755 index 0000000000000000000000000000000000000000..9ed5782656a31ba09d566aa405283eecba5caa8a --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/libmpdec/literature/bignum.txt b/python_part/python/Modules/_decimal/libmpdec/literature/bignum.txt new file mode 100755 index 0000000000000000000000000000000000000000..f34ff67c612ab4ebbff4bd16768efc6dddb47437 --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/libmpdec/literature/fnt.py b/python_part/python/Modules/_decimal/libmpdec/literature/fnt.py new file mode 100755 index 0000000000000000000000000000000000000000..6363536da648737d36ce02690f1411f8ce470c55 --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/libmpdec/literature/matrix-transform.txt b/python_part/python/Modules/_decimal/libmpdec/literature/matrix-transform.txt new file mode 100755 index 0000000000000000000000000000000000000000..701d85d6b43c8145b4d55ef841c4de9327bdeecf --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/libmpdec/literature/mulmod-64.txt b/python_part/python/Modules/_decimal/libmpdec/literature/mulmod-64.txt new file mode 100755 index 0000000000000000000000000000000000000000..029b8de3d7c925b99a8ff2985eeb3cc959130441 --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/libmpdec/literature/mulmod-ppro.txt b/python_part/python/Modules/_decimal/libmpdec/literature/mulmod-ppro.txt new file mode 100755 index 0000000000000000000000000000000000000000..4d17a928e6eae54dd1df136fc8bec7e591a6652f --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/libmpdec/literature/six-step.txt b/python_part/python/Modules/_decimal/libmpdec/literature/six-step.txt new file mode 100755 index 0000000000000000000000000000000000000000..8e45f48758478aea2dc1377fc679a3bb766fdcdd --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/libmpdec/literature/umodarith.lisp b/python_part/python/Modules/_decimal/libmpdec/literature/umodarith.lisp new file mode 100755 index 0000000000000000000000000000000000000000..99d71c373d1abd66b41dc254e0770b334e3f44e1 --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/libmpdec/memory.c b/python_part/python/Modules/_decimal/libmpdec/memory.c new file mode 100755 index 0000000000000000000000000000000000000000..a854e09911bd3321aa69eeab321ffbfbd7f59c62 --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/libmpdec/mpalloc.h b/python_part/python/Modules/_decimal/libmpdec/mpalloc.h new file mode 100755 index 0000000000000000000000000000000000000000..efd711953a39827aa45d776003bcf50c58704805 --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/libmpdec/mpdecimal.c b/python_part/python/Modules/_decimal/libmpdec/mpdecimal.c new file mode 100755 index 0000000000000000000000000000000000000000..bfa8bb343e60c1db28c2f11fa07baa7c8d20d796 --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/libmpdec/mpdecimal.h b/python_part/python/Modules/_decimal/libmpdec/mpdecimal.h new file mode 100755 index 0000000000000000000000000000000000000000..3e9c8185c35a70b46c323437d30b042f559b41f3 --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/libmpdec/numbertheory.c b/python_part/python/Modules/_decimal/libmpdec/numbertheory.c new file mode 100755 index 0000000000000000000000000000000000000000..4e035477e280001cdb3ba69418e0270215b88513 --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/libmpdec/numbertheory.h b/python_part/python/Modules/_decimal/libmpdec/numbertheory.h new file mode 100755 index 0000000000000000000000000000000000000000..e94c157910c83e99c4425d0d81bf96a9ed9e23fa --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/libmpdec/sixstep.c b/python_part/python/Modules/_decimal/libmpdec/sixstep.c new file mode 100755 index 0000000000000000000000000000000000000000..92d513ebe18286ad402d046101bd0744b45aab7c --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/libmpdec/sixstep.h b/python_part/python/Modules/_decimal/libmpdec/sixstep.h new file mode 100755 index 0000000000000000000000000000000000000000..4a8b015e3a9b90e807734378e03c72310e5af135 --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/libmpdec/transpose.c b/python_part/python/Modules/_decimal/libmpdec/transpose.c new file mode 100755 index 0000000000000000000000000000000000000000..55d6d8992279009f320e8479514f71412195fa48 --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/libmpdec/transpose.h b/python_part/python/Modules/_decimal/libmpdec/transpose.h new file mode 100755 index 0000000000000000000000000000000000000000..e1cd1fa17dd7730237f02e01f38fc37cf96c28cf --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/libmpdec/typearith.h b/python_part/python/Modules/_decimal/libmpdec/typearith.h new file mode 100755 index 0000000000000000000000000000000000000000..405237dac516ad0c5666a31842e6519403978521 --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/libmpdec/umodarith.h b/python_part/python/Modules/_decimal/libmpdec/umodarith.h new file mode 100755 index 0000000000000000000000000000000000000000..68d15188cb39e5accf9dff257d1c5c47aceae20a --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/libmpdec/vccompat.h b/python_part/python/Modules/_decimal/libmpdec/vccompat.h new file mode 100755 index 0000000000000000000000000000000000000000..dd131d8da2645c66fa241e55ca55d126f1447dfc --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/libmpdec/vcdiv64.asm b/python_part/python/Modules/_decimal/libmpdec/vcdiv64.asm new file mode 100755 index 0000000000000000000000000000000000000000..6b6645673ab5ae6cc6013435de5d257c1d5297cb --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/libmpdec/vcstdint.h b/python_part/python/Modules/_decimal/libmpdec/vcstdint.h new file mode 100755 index 0000000000000000000000000000000000000000..17dcad4541ee5c201cf10d70e05510949b536462 --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/tests/README.txt b/python_part/python/Modules/_decimal/tests/README.txt new file mode 100755 index 0000000000000000000000000000000000000000..97b6ff68a56fb7abaf0cbf03250962431c055bcc --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/tests/bench.py b/python_part/python/Modules/_decimal/tests/bench.py new file mode 100755 index 0000000000000000000000000000000000000000..3726db194e032f24a975db001d178f9cb3792049 --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/tests/bignum.py b/python_part/python/Modules/_decimal/tests/bignum.py new file mode 100755 index 0000000000000000000000000000000000000000..a67e161ddf098fb125b5437838458009c5b30dea --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/tests/deccheck.py b/python_part/python/Modules/_decimal/tests/deccheck.py new file mode 100755 index 0000000000000000000000000000000000000000..f907531e1ffa58b52e9e5a48b6f5e70a7d35c0ce --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/tests/formathelper.py b/python_part/python/Modules/_decimal/tests/formathelper.py new file mode 100755 index 0000000000000000000000000000000000000000..19b2aad4a503b1e2bc1904ac50a03550810ac9d5 --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/tests/randdec.py b/python_part/python/Modules/_decimal/tests/randdec.py new file mode 100755 index 0000000000000000000000000000000000000000..d667f79f2c92f3b27a492515fba9ce82c0e1a34f --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/tests/randfloat.py b/python_part/python/Modules/_decimal/tests/randfloat.py new file mode 100755 index 0000000000000000000000000000000000000000..16873035689cf30495658e1f8f5883cae58b98bd --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/tests/runall-memorydebugger.sh b/python_part/python/Modules/_decimal/tests/runall-memorydebugger.sh new file mode 100755 index 0000000000000000000000000000000000000000..7f3e527461871a61b83660ca54dc357d9fb4e929 --- /dev/null +++ b/python_part/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_part/python/Modules/_decimal/tests/runall.bat b/python_part/python/Modules/_decimal/tests/runall.bat new file mode 100755 index 0000000000000000000000000000000000000000..f278ef33b5fc5b071053fd2bfc6abf003596d840 --- /dev/null +++ b/python_part/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_part/python/Modules/_elementtree.c b/python_part/python/Modules/_elementtree.c new file mode 100755 index 0000000000000000000000000000000000000000..a96e3f43b5597f99cf1358dc534ef38b699dbd61 --- /dev/null +++ b/python_part/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_part/python/Modules/_functoolsmodule.c b/python_part/python/Modules/_functoolsmodule.c new file mode 100755 index 0000000000000000000000000000000000000000..148d051714f899709adaa2941d32de0f25cb700c --- /dev/null +++ b/python_part/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_part/python/Modules/_gdbmmodule.c b/python_part/python/Modules/_gdbmmodule.c new file mode 100755 index 0000000000000000000000000000000000000000..34e205fd40f094624566ce9078b27c48d723b1b5 --- /dev/null +++ b/python_part/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_part/python/Modules/_hashopenssl.c b/python_part/python/Modules/_hashopenssl.c new file mode 100755 index 0000000000000000000000000000000000000000..8c710968cbe271a8652afa75936dbf7225313f65 --- /dev/null +++ b/python_part/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_part/python/Modules/_heapqmodule.c b/python_part/python/Modules/_heapqmodule.c new file mode 100755 index 0000000000000000000000000000000000000000..6bc18b5f82fb82db52cec8b6a90256db928196b9 --- /dev/null +++ b/python_part/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_part/python/Modules/_io/_iomodule.c b/python_part/python/Modules/_io/_iomodule.c new file mode 100755 index 0000000000000000000000000000000000000000..49ed2cb00de52fcad6325c449ea89782454e7896 --- /dev/null +++ b/python_part/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_part/python/Modules/_io/_iomodule.h b/python_part/python/Modules/_io/_iomodule.h new file mode 100755 index 0000000000000000000000000000000000000000..4d318acd0b3f8dee79ef95f2a9d28b340bf5d013 --- /dev/null +++ b/python_part/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_part/python/Modules/_io/bufferedio.c b/python_part/python/Modules/_io/bufferedio.c new file mode 100755 index 0000000000000000000000000000000000000000..ad7a8c9d264270acd0ef605c0fd5d5fa7f589427 --- /dev/null +++ b/python_part/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_part/python/Modules/_io/bytesio.c b/python_part/python/Modules/_io/bytesio.c new file mode 100755 index 0000000000000000000000000000000000000000..3cf6402e75f7d5c4505bb10c65518dfafcb01c63 --- /dev/null +++ b/python_part/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_part/python/Modules/_io/clinic/_iomodule.c.h b/python_part/python/Modules/_io/clinic/_iomodule.c.h new file mode 100755 index 0000000000000000000000000000000000000000..1a9651d340813f03dc84800f08758b897b0515b1 --- /dev/null +++ b/python_part/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_part/python/Modules/_io/clinic/bufferedio.c.h b/python_part/python/Modules/_io/clinic/bufferedio.c.h new file mode 100755 index 0000000000000000000000000000000000000000..72841fcb6779c7f872c643926ff068022da7f5ef --- /dev/null +++ b/python_part/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_part/python/Modules/_io/clinic/bytesio.c.h b/python_part/python/Modules/_io/clinic/bytesio.c.h new file mode 100755 index 0000000000000000000000000000000000000000..83cd490dc59804e4ac46d12467703d86d2c3f0ed --- /dev/null +++ b/python_part/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_part/python/Modules/_io/clinic/fileio.c.h b/python_part/python/Modules/_io/clinic/fileio.c.h new file mode 100755 index 0000000000000000000000000000000000000000..53e7067cf7a741696b1e156a0eb56f2bd31b873e --- /dev/null +++ b/python_part/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_part/python/Modules/_io/clinic/iobase.c.h b/python_part/python/Modules/_io/clinic/iobase.c.h new file mode 100755 index 0000000000000000000000000000000000000000..ddaff7b5d135d8c7f0e1c0dc55dc10ef473f4b5f --- /dev/null +++ b/python_part/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_part/python/Modules/_io/clinic/stringio.c.h b/python_part/python/Modules/_io/clinic/stringio.c.h new file mode 100755 index 0000000000000000000000000000000000000000..77a720c2a6ff10e46861df18733ed9795de02185 --- /dev/null +++ b/python_part/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_part/python/Modules/_io/clinic/textio.c.h b/python_part/python/Modules/_io/clinic/textio.c.h new file mode 100755 index 0000000000000000000000000000000000000000..b8b507543ea81c5a23a47d96445cb1280f835f56 --- /dev/null +++ b/python_part/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_part/python/Modules/_io/clinic/winconsoleio.c.h b/python_part/python/Modules/_io/clinic/winconsoleio.c.h new file mode 100755 index 0000000000000000000000000000000000000000..3e501a58537165cc55f1e43e097ca240e1b1b105 --- /dev/null +++ b/python_part/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_part/python/Modules/_io/fileio.c b/python_part/python/Modules/_io/fileio.c new file mode 100755 index 0000000000000000000000000000000000000000..482d08f9f23b2af2a1da95171622a487dcbd8e43 --- /dev/null +++ b/python_part/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_part/python/Modules/_io/iobase.c b/python_part/python/Modules/_io/iobase.c new file mode 100755 index 0000000000000000000000000000000000000000..fab450977ffa7cc4bb0ed8ad0dc96813be39dc72 --- /dev/null +++ b/python_part/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_part/python/Modules/_io/stringio.c b/python_part/python/Modules/_io/stringio.c new file mode 100755 index 0000000000000000000000000000000000000000..8b5fa7a369f38ca1bec765a9c7f9dd14e79aa383 --- /dev/null +++ b/python_part/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_part/python/Modules/_io/textio.c b/python_part/python/Modules/_io/textio.c new file mode 100755 index 0000000000000000000000000000000000000000..642c614f07dcb9cb5efb372828b65bb3ff9259f2 --- /dev/null +++ b/python_part/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_part/python/Modules/_io/winconsoleio.c b/python_part/python/Modules/_io/winconsoleio.c new file mode 100755 index 0000000000000000000000000000000000000000..ea5d24f950a1e24f79a5b21c595ce1bba3f3e0d8 --- /dev/null +++ b/python_part/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_part/python/Modules/_json.c b/python_part/python/Modules/_json.c new file mode 100755 index 0000000000000000000000000000000000000000..43a6ab36e0a3ecd6f2d00866a07c647d08b4dc99 --- /dev/null +++ b/python_part/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_part/python/Modules/_localemodule.c b/python_part/python/Modules/_localemodule.c new file mode 100755 index 0000000000000000000000000000000000000000..d54f70904e456891970bfaef9600b638e37ee381 --- /dev/null +++ b/python_part/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_part/python/Modules/_lsprof.c b/python_part/python/Modules/_lsprof.c new file mode 100755 index 0000000000000000000000000000000000000000..c5a6f4445872cad30b35b14f53c11aedc41623a7 --- /dev/null +++ b/python_part/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_part/python/Modules/_lzmamodule.c b/python_part/python/Modules/_lzmamodule.c new file mode 100755 index 0000000000000000000000000000000000000000..27e9a913e96644112e6f9fe6c4b44f79fb25be63 --- /dev/null +++ b/python_part/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_part/python/Modules/_math.c b/python_part/python/Modules/_math.c new file mode 100755 index 0000000000000000000000000000000000000000..02d8f1c43c80070f01076b1ec09a1119e79e925c --- /dev/null +++ b/python_part/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_part/python/Modules/_math.h b/python_part/python/Modules/_math.h new file mode 100755 index 0000000000000000000000000000000000000000..398b7e8874af00bc52a3ba6e02ec1d4ba988bb70 --- /dev/null +++ b/python_part/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_part/python/Modules/_multiprocessing/clinic/posixshmem.c.h b/python_part/python/Modules/_multiprocessing/clinic/posixshmem.c.h new file mode 100755 index 0000000000000000000000000000000000000000..a99f0d2aae1dcb2121ee644d7f5ee2f9d970379a --- /dev/null +++ b/python_part/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_part/python/Modules/_multiprocessing/multiprocessing.c b/python_part/python/Modules/_multiprocessing/multiprocessing.c new file mode 100755 index 0000000000000000000000000000000000000000..806e638340f7af0dcba9671f7184da62828b459b --- /dev/null +++ b/python_part/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_part/python/Modules/_multiprocessing/multiprocessing.h b/python_part/python/Modules/_multiprocessing/multiprocessing.h new file mode 100755 index 0000000000000000000000000000000000000000..512bc17f23d46b7c2a536a274905ac930c24a984 --- /dev/null +++ b/python_part/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_part/python/Modules/_multiprocessing/posixshmem.c b/python_part/python/Modules/_multiprocessing/posixshmem.c new file mode 100755 index 0000000000000000000000000000000000000000..2049dbbc6fa83baf595f61052595a5c576ce272a --- /dev/null +++ b/python_part/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_part/python/Modules/_multiprocessing/semaphore.c b/python_part/python/Modules/_multiprocessing/semaphore.c new file mode 100755 index 0000000000000000000000000000000000000000..4be2deae377504bf2e2f7fbba95c1504eb74356a --- /dev/null +++ b/python_part/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_part/python/Modules/_opcode.c b/python_part/python/Modules/_opcode.c new file mode 100755 index 0000000000000000000000000000000000000000..42a8732694afef6e7dbfcbfc4f5d56d4ab87a933 --- /dev/null +++ b/python_part/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_part/python/Modules/_operator.c b/python_part/python/Modules/_operator.c new file mode 100755 index 0000000000000000000000000000000000000000..a8165482b833449f520e65ce9c041e730c9af31e --- /dev/null +++ b/python_part/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_part/python/Modules/_pickle.c b/python_part/python/Modules/_pickle.c new file mode 100755 index 0000000000000000000000000000000000000000..42ce62fc7cdf4e18e3af6d18a256e1df15b96221 --- /dev/null +++ b/python_part/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_part/python/Modules/_posixsubprocess.c b/python_part/python/Modules/_posixsubprocess.c new file mode 100755 index 0000000000000000000000000000000000000000..05c051c6125f407b6764e70e3d21bb34f5843cd7 --- /dev/null +++ b/python_part/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_part/python/Modules/_queuemodule.c b/python_part/python/Modules/_queuemodule.c new file mode 100755 index 0000000000000000000000000000000000000000..e033da50a5ee3b47addf3b6c63515426ae27e83a --- /dev/null +++ b/python_part/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_part/python/Modules/_randommodule.c b/python_part/python/Modules/_randommodule.c new file mode 100755 index 0000000000000000000000000000000000000000..4e9ac4073c77740925f27cbeaaedaa8e6b2b2558 --- /dev/null +++ b/python_part/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_part/python/Modules/_scproxy.c b/python_part/python/Modules/_scproxy.c new file mode 100755 index 0000000000000000000000000000000000000000..9b6b2d684f7efde9edf89f072ce97e27ac823871 --- /dev/null +++ b/python_part/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_part/python/Modules/_sha3/README.txt b/python_part/python/Modules/_sha3/README.txt new file mode 100755 index 0000000000000000000000000000000000000000..e34b1d12f702fa45fd0a065b4dc2f1f54d95928d --- /dev/null +++ b/python_part/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_part/python/Modules/_sha3/cleanup.py b/python_part/python/Modules/_sha3/cleanup.py new file mode 100755 index 0000000000000000000000000000000000000000..4f53681b49e67bc200efab1eee5cf9cf365b5fe7 --- /dev/null +++ b/python_part/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_part/python/Modules/_sha3/clinic/sha3module.c.h b/python_part/python/Modules/_sha3/clinic/sha3module.c.h new file mode 100755 index 0000000000000000000000000000000000000000..554442df0ec28667288fe80298963c8d570b5908 --- /dev/null +++ b/python_part/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_part/python/Modules/_sha3/kcp/KeccakHash.c b/python_part/python/Modules/_sha3/kcp/KeccakHash.c new file mode 100755 index 0000000000000000000000000000000000000000..e09fb43cacea1d099a2b1eb1422e4e762cc36f4c --- /dev/null +++ b/python_part/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_part/python/Modules/_sha3/kcp/KeccakHash.h b/python_part/python/Modules/_sha3/kcp/KeccakHash.h new file mode 100755 index 0000000000000000000000000000000000000000..bbd3dc64a2285be577123bc84913d8793eb7e66b --- /dev/null +++ b/python_part/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_part/python/Modules/_sha3/kcp/KeccakP-1600-64.macros b/python_part/python/Modules/_sha3/kcp/KeccakP-1600-64.macros new file mode 100755 index 0000000000000000000000000000000000000000..1f11fe3e79fbbaebd7fc6af61c0ea831f2786617 --- /dev/null +++ b/python_part/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_part/python/Modules/_sha3/kcp/KeccakP-1600-SnP-opt32.h b/python_part/python/Modules/_sha3/kcp/KeccakP-1600-SnP-opt32.h new file mode 100755 index 0000000000000000000000000000000000000000..6cf765e6ce11e14d0fae72156fad7138a122679d --- /dev/null +++ b/python_part/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_part/python/Modules/_sha3/kcp/KeccakP-1600-SnP-opt64.h b/python_part/python/Modules/_sha3/kcp/KeccakP-1600-SnP-opt64.h new file mode 100755 index 0000000000000000000000000000000000000000..889a31a79444c5b68e541e5f2867857b5c12a215 --- /dev/null +++ b/python_part/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_part/python/Modules/_sha3/kcp/KeccakP-1600-SnP.h b/python_part/python/Modules/_sha3/kcp/KeccakP-1600-SnP.h new file mode 100755 index 0000000000000000000000000000000000000000..0b23f09a6a442fde84c6f360b6fc388040c96299 --- /dev/null +++ b/python_part/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_part/python/Modules/_sha3/kcp/KeccakP-1600-inplace32BI.c b/python_part/python/Modules/_sha3/kcp/KeccakP-1600-inplace32BI.c new file mode 100755 index 0000000000000000000000000000000000000000..a2f9ffea93259d964b95f41ec45ec535ad519d49 --- /dev/null +++ b/python_part/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_part/python/Modules/_sha3/kcp/KeccakP-1600-opt64-config.h b/python_part/python/Modules/_sha3/kcp/KeccakP-1600-opt64-config.h new file mode 100755 index 0000000000000000000000000000000000000000..9501c64b186aa94505419d3a180959e0c344c5a5 --- /dev/null +++ b/python_part/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_part/python/Modules/_sha3/kcp/KeccakP-1600-opt64.c b/python_part/python/Modules/_sha3/kcp/KeccakP-1600-opt64.c new file mode 100755 index 0000000000000000000000000000000000000000..c90010dd9256c14fe4a1619d91936773d8c7a7ed --- /dev/null +++ b/python_part/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_part/python/Modules/_sha3/kcp/KeccakP-1600-unrolling.macros b/python_part/python/Modules/_sha3/kcp/KeccakP-1600-unrolling.macros new file mode 100755 index 0000000000000000000000000000000000000000..405ce29724cedd67143e937e3e9bb3de17fbc7bd --- /dev/null +++ b/python_part/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_part/python/Modules/_sha3/kcp/KeccakSponge.c b/python_part/python/Modules/_sha3/kcp/KeccakSponge.c new file mode 100755 index 0000000000000000000000000000000000000000..afdb73172f3478f8044a3bb9a52b51af4bd28943 --- /dev/null +++ b/python_part/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_part/python/Modules/_sha3/kcp/KeccakSponge.h b/python_part/python/Modules/_sha3/kcp/KeccakSponge.h new file mode 100755 index 0000000000000000000000000000000000000000..0f4badcac059e9402671ce64bc45287e3a31f649 --- /dev/null +++ b/python_part/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_part/python/Modules/_sha3/kcp/KeccakSponge.inc b/python_part/python/Modules/_sha3/kcp/KeccakSponge.inc new file mode 100755 index 0000000000000000000000000000000000000000..e10739deafa836d571fb46fc4eed98f75b1dc00e --- /dev/null +++ b/python_part/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_part/python/Modules/_sha3/kcp/PlSnP-Fallback.inc b/python_part/python/Modules/_sha3/kcp/PlSnP-Fallback.inc new file mode 100755 index 0000000000000000000000000000000000000000..3a9119ab4b6aa894fb0d12ac07523fd83ae3b463 --- /dev/null +++ b/python_part/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_part/python/Modules/_sha3/kcp/align.h b/python_part/python/Modules/_sha3/kcp/align.h new file mode 100755 index 0000000000000000000000000000000000000000..6650fe8c3cf0ef70bee16d8c28ebdd8e8a656c5e --- /dev/null +++ b/python_part/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_part/python/Modules/_sha3/sha3module.c b/python_part/python/Modules/_sha3/sha3module.c new file mode 100755 index 0000000000000000000000000000000000000000..c1fb6185e243daf302f79bac42556c0b5ea13acb --- /dev/null +++ b/python_part/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_part/python/Modules/_sqlite/cache.c b/python_part/python/Modules/_sqlite/cache.c new file mode 100755 index 0000000000000000000000000000000000000000..4d4180421871de21ae82004ac58bc009ed224f0e --- /dev/null +++ b/python_part/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_part/python/Modules/_sqlite/cache.h b/python_part/python/Modules/_sqlite/cache.h new file mode 100755 index 0000000000000000000000000000000000000000..529010967c4f3a99c8a4a11a2b993f9bdcae8196 --- /dev/null +++ b/python_part/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_part/python/Modules/_sqlite/connection.c b/python_part/python/Modules/_sqlite/connection.c new file mode 100755 index 0000000000000000000000000000000000000000..d1d5f9fd07cd7e2f1925cbcd1bfab97acecaaaa3 --- /dev/null +++ b/python_part/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_part/python/Modules/_sqlite/connection.h b/python_part/python/Modules/_sqlite/connection.h new file mode 100755 index 0000000000000000000000000000000000000000..206085e00a00c707fee85abadf19c75da8819fd9 --- /dev/null +++ b/python_part/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_part/python/Modules/_sqlite/cursor.c b/python_part/python/Modules/_sqlite/cursor.c new file mode 100755 index 0000000000000000000000000000000000000000..8cfa6e50e822250a8efd4854d7ba2cdc6367fa1e --- /dev/null +++ b/python_part/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_part/python/Modules/_sqlite/cursor.h b/python_part/python/Modules/_sqlite/cursor.h new file mode 100755 index 0000000000000000000000000000000000000000..4a20e756f7829d9a9a0b210cac9c9f72da5bbc4b --- /dev/null +++ b/python_part/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_part/python/Modules/_sqlite/microprotocols.c b/python_part/python/Modules/_sqlite/microprotocols.c new file mode 100755 index 0000000000000000000000000000000000000000..c23b09f56b5bd1cb4deebc0906057728dcab338e --- /dev/null +++ b/python_part/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_part/python/Modules/_sqlite/microprotocols.h b/python_part/python/Modules/_sqlite/microprotocols.h new file mode 100755 index 0000000000000000000000000000000000000000..5418c2b98fd7519dd235f40d146a2a0069f6281e --- /dev/null +++ b/python_part/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_part/python/Modules/_sqlite/module.c b/python_part/python/Modules/_sqlite/module.c new file mode 100755 index 0000000000000000000000000000000000000000..d3ce2839eecc3c94841c9229e093c17bf34554bb --- /dev/null +++ b/python_part/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_part/python/Modules/_sqlite/module.h b/python_part/python/Modules/_sqlite/module.h new file mode 100755 index 0000000000000000000000000000000000000000..3185ec978885676830e6b251da9604628969b28d --- /dev/null +++ b/python_part/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_part/python/Modules/_sqlite/prepare_protocol.c b/python_part/python/Modules/_sqlite/prepare_protocol.c new file mode 100755 index 0000000000000000000000000000000000000000..181c7edf96b45c386010da0fcdbdad6007071261 --- /dev/null +++ b/python_part/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_part/python/Modules/_sqlite/prepare_protocol.h b/python_part/python/Modules/_sqlite/prepare_protocol.h new file mode 100755 index 0000000000000000000000000000000000000000..3998a55e51cafeed4cf947b22e19fba5e82f9bd9 --- /dev/null +++ b/python_part/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_part/python/Modules/_sqlite/row.c b/python_part/python/Modules/_sqlite/row.c new file mode 100755 index 0000000000000000000000000000000000000000..4b47108278a0ab4d6c1043ae48f7c40aa31e11bf --- /dev/null +++ b/python_part/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_part/python/Modules/_sqlite/row.h b/python_part/python/Modules/_sqlite/row.h new file mode 100755 index 0000000000000000000000000000000000000000..4ad506f8dd968731f28d44808fa182f5078545d6 --- /dev/null +++ b/python_part/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_part/python/Modules/_sqlite/statement.c b/python_part/python/Modules/_sqlite/statement.c new file mode 100755 index 0000000000000000000000000000000000000000..70fd95f0fbbfb099412a8a79c0c5fa2a4449ac75 --- /dev/null +++ b/python_part/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_part/python/Modules/_sqlite/statement.h b/python_part/python/Modules/_sqlite/statement.h new file mode 100755 index 0000000000000000000000000000000000000000..5002f02dc5b39261ba3c842b0ed2af82091945a7 --- /dev/null +++ b/python_part/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_part/python/Modules/_sqlite/util.c b/python_part/python/Modules/_sqlite/util.c new file mode 100755 index 0000000000000000000000000000000000000000..3fa671d052b0d83c28cdbb6491e5f60300da11d9 --- /dev/null +++ b/python_part/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_part/python/Modules/_sqlite/util.h b/python_part/python/Modules/_sqlite/util.h new file mode 100755 index 0000000000000000000000000000000000000000..626191118f9257c0734c9dfd76c520e38fd4a2ed --- /dev/null +++ b/python_part/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_part/python/Modules/_sre.c b/python_part/python/Modules/_sre.c new file mode 100755 index 0000000000000000000000000000000000000000..d4fe588cbe27c601cbd8ba4138bedd3e6e4ec371 --- /dev/null +++ b/python_part/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_part/python/Modules/_ssl.c b/python_part/python/Modules/_ssl.c new file mode 100755 index 0000000000000000000000000000000000000000..7c6927bc130e032a0f69571d128f00cb783e6d0d --- /dev/null +++ b/python_part/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_part/python/Modules/_ssl/debughelpers.c b/python_part/python/Modules/_ssl/debughelpers.c new file mode 100755 index 0000000000000000000000000000000000000000..af56f9d28d16427e4500d0c1742fd7853d6ffe68 --- /dev/null +++ b/python_part/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_part/python/Modules/_ssl_data.h b/python_part/python/Modules/_ssl_data.h new file mode 100755 index 0000000000000000000000000000000000000000..8f2994f52dfef86874d76aab5d10d65e3c15797b --- /dev/null +++ b/python_part/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_part/python/Modules/_ssl_data_111.h b/python_part/python/Modules/_ssl_data_111.h new file mode 100755 index 0000000000000000000000000000000000000000..85a2f7ec1561ea8178d407015fe3577517a41a7d --- /dev/null +++ b/python_part/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_part/python/Modules/_ssl_data_300.h b/python_part/python/Modules/_ssl_data_300.h new file mode 100755 index 0000000000000000000000000000000000000000..6be8b24ee1a02174cb69a8da9c15411aef71ed75 --- /dev/null +++ b/python_part/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_part/python/Modules/_stat.c b/python_part/python/Modules/_stat.c new file mode 100755 index 0000000000000000000000000000000000000000..7a799af0cada26e7329336e5b79c67ac06b657a5 --- /dev/null +++ b/python_part/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_part/python/Modules/_statisticsmodule.c b/python_part/python/Modules/_statisticsmodule.c new file mode 100755 index 0000000000000000000000000000000000000000..a646e96d0165c084e621e711e5d9bb03e0529f46 --- /dev/null +++ b/python_part/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_part/python/Modules/_struct.c b/python_part/python/Modules/_struct.c new file mode 100755 index 0000000000000000000000000000000000000000..64a9827e83aaeed473493518ce0231de4ae0a176 --- /dev/null +++ b/python_part/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_part/python/Modules/_testbuffer.c b/python_part/python/Modules/_testbuffer.c new file mode 100755 index 0000000000000000000000000000000000000000..d7d3cc8d0d53a67d4c76fb51a185d5e30622c15a --- /dev/null +++ b/python_part/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_part/python/Modules/_testcapimodule.c b/python_part/python/Modules/_testcapimodule.c new file mode 100755 index 0000000000000000000000000000000000000000..0d37e4785f0e952682499821daab5a438230f95a --- /dev/null +++ b/python_part/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_part/python/Modules/_testimportmultiple.c b/python_part/python/Modules/_testimportmultiple.c new file mode 100755 index 0000000000000000000000000000000000000000..1caeb66eb8c85890e2105e3b40716572bf7a5c78 --- /dev/null +++ b/python_part/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_part/python/Modules/_testinternalcapi.c b/python_part/python/Modules/_testinternalcapi.c new file mode 100755 index 0000000000000000000000000000000000000000..3a931cae1fc2eec6b3e58f5e197750511ad6fb65 --- /dev/null +++ b/python_part/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_part/python/Modules/_testmultiphase.c b/python_part/python/Modules/_testmultiphase.c new file mode 100755 index 0000000000000000000000000000000000000000..4933abbabbe307e6178df2db7df8100d22439aec --- /dev/null +++ b/python_part/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_part/python/Modules/_threadmodule.c b/python_part/python/Modules/_threadmodule.c new file mode 100755 index 0000000000000000000000000000000000000000..fadf57aaa762e1b1e899c495fceccc87c8abd4dd --- /dev/null +++ b/python_part/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_part/python/Modules/_tkinter.c b/python_part/python/Modules/_tkinter.c new file mode 100755 index 0000000000000000000000000000000000000000..8825c83083443c54f612dc8864eb41f485ef6db8 --- /dev/null +++ b/python_part/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_part/python/Modules/_tracemalloc.c b/python_part/python/Modules/_tracemalloc.c new file mode 100755 index 0000000000000000000000000000000000000000..cbcf55f817435f5e173da494e98a5f3c706a0af2 --- /dev/null +++ b/python_part/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_part/python/Modules/_uuidmodule.c b/python_part/python/Modules/_uuidmodule.c new file mode 100755 index 0000000000000000000000000000000000000000..71568642c1c58c609887c0031fce33ea28a92f85 --- /dev/null +++ b/python_part/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_part/python/Modules/_weakref.c b/python_part/python/Modules/_weakref.c new file mode 100755 index 0000000000000000000000000000000000000000..c1238e00d35f4aa8315cd8d29790a1663a24dbc2 --- /dev/null +++ b/python_part/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_part/python/Modules/_winapi.c b/python_part/python/Modules/_winapi.c new file mode 100755 index 0000000000000000000000000000000000000000..6cdd09eb686fa5de561566c2a8db3c189006574b --- /dev/null +++ b/python_part/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_part/python/Modules/_xxsubinterpretersmodule.c b/python_part/python/Modules/_xxsubinterpretersmodule.c new file mode 100755 index 0000000000000000000000000000000000000000..bda2a256ed9f7b2387a4c87534784acdd4f121f4 --- /dev/null +++ b/python_part/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_part/python/Modules/_xxtestfuzz/README.rst b/python_part/python/Modules/_xxtestfuzz/README.rst new file mode 100755 index 0000000000000000000000000000000000000000..42bd02a03cbeddac2c3485a023c6a26b4c01a870 --- /dev/null +++ b/python_part/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_part/python/Modules/_xxtestfuzz/_xxtestfuzz.c b/python_part/python/Modules/_xxtestfuzz/_xxtestfuzz.c new file mode 100755 index 0000000000000000000000000000000000000000..781dd23500a29ed006394015deaa9ae0de7b6977 --- /dev/null +++ b/python_part/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_part/python/Modules/_xxtestfuzz/dictionaries/fuzz_json_loads.dict b/python_part/python/Modules/_xxtestfuzz/dictionaries/fuzz_json_loads.dict new file mode 100755 index 0000000000000000000000000000000000000000..ad64917ccc2c08457d2adae8cfdb7f666d0a9acb --- /dev/null +++ b/python_part/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_part/python/Modules/_xxtestfuzz/dictionaries/fuzz_sre_compile.dict b/python_part/python/Modules/_xxtestfuzz/dictionaries/fuzz_sre_compile.dict new file mode 100755 index 0000000000000000000000000000000000000000..961306a87901d0aaa394100a582f07f913ba58c8 --- /dev/null +++ b/python_part/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_part/python/Modules/_xxtestfuzz/fuzz_csv_reader_corpus/test.csv b/python_part/python/Modules/_xxtestfuzz/fuzz_csv_reader_corpus/test.csv new file mode 100755 index 0000000000000000000000000000000000000000..8b7887d0f1d2426354ec0d01fb06768604406dc0 Binary files /dev/null and b/python_part/python/Modules/_xxtestfuzz/fuzz_csv_reader_corpus/test.csv differ diff --git a/python_part/python/Modules/_xxtestfuzz/fuzz_json_loads_corpus/empty_array.json b/python_part/python/Modules/_xxtestfuzz/fuzz_json_loads_corpus/empty_array.json new file mode 100755 index 0000000000000000000000000000000000000000..fe51488c7066f6687ef680d6bfaa4f7768ef205c --- /dev/null +++ b/python_part/python/Modules/_xxtestfuzz/fuzz_json_loads_corpus/empty_array.json @@ -0,0 +1 @@ +[] diff --git a/python_part/python/Modules/_xxtestfuzz/fuzz_json_loads_corpus/empty_object.json b/python_part/python/Modules/_xxtestfuzz/fuzz_json_loads_corpus/empty_object.json new file mode 100755 index 0000000000000000000000000000000000000000..0967ef424bce6791893e9a57bb952f80fd536e93 --- /dev/null +++ b/python_part/python/Modules/_xxtestfuzz/fuzz_json_loads_corpus/empty_object.json @@ -0,0 +1 @@ +{} diff --git a/python_part/python/Modules/_xxtestfuzz/fuzz_json_loads_corpus/pass1.json b/python_part/python/Modules/_xxtestfuzz/fuzz_json_loads_corpus/pass1.json new file mode 100755 index 0000000000000000000000000000000000000000..70e26854369282e625e75b302782f581e610f2b3 --- /dev/null +++ b/python_part/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_part/python/Modules/_xxtestfuzz/fuzz_json_loads_corpus/pass2.json b/python_part/python/Modules/_xxtestfuzz/fuzz_json_loads_corpus/pass2.json new file mode 100755 index 0000000000000000000000000000000000000000..d3c63c7ad845e4cedd0c70d13102b38c51ec197a --- /dev/null +++ b/python_part/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_part/python/Modules/_xxtestfuzz/fuzz_json_loads_corpus/pass3.json b/python_part/python/Modules/_xxtestfuzz/fuzz_json_loads_corpus/pass3.json new file mode 100755 index 0000000000000000000000000000000000000000..4528d51f1ac615e7e11dbb1321dc99187705f0d8 --- /dev/null +++ b/python_part/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_part/python/Modules/_xxtestfuzz/fuzz_json_loads_corpus/simple_array.json b/python_part/python/Modules/_xxtestfuzz/fuzz_json_loads_corpus/simple_array.json new file mode 100755 index 0000000000000000000000000000000000000000..ce1e6ecaec72f4e7bd685d2bef5ed837ec5e4a90 --- /dev/null +++ b/python_part/python/Modules/_xxtestfuzz/fuzz_json_loads_corpus/simple_array.json @@ -0,0 +1 @@ +[1, 2, 3, "abcd", "xyz"] diff --git a/python_part/python/Modules/_xxtestfuzz/fuzz_sre_compile_corpus/anchor_links b/python_part/python/Modules/_xxtestfuzz/fuzz_sre_compile_corpus/anchor_links new file mode 100755 index 0000000000000000000000000000000000000000..d99247ccadfd18fa94805369dc56839ff5a257ea --- /dev/null +++ b/python_part/python/Modules/_xxtestfuzz/fuzz_sre_compile_corpus/anchor_links @@ -0,0 +1 @@ +XX] diff --git a/python_part/python/Modules/_xxtestfuzz/fuzz_sre_compile_corpus/characters b/python_part/python/Modules/_xxtestfuzz/fuzz_sre_compile_corpus/characters new file mode 100755 index 0000000000000000000000000000000000000000..0c67ee7dfc1b5d13f7a9ee4520e55b5053e903bf --- /dev/null +++ b/python_part/python/Modules/_xxtestfuzz/fuzz_sre_compile_corpus/characters @@ -0,0 +1 @@ +XX^(Tim|Robert)\s+the\s+(Enchanter|Shrubber)$ diff --git a/python_part/python/Modules/_xxtestfuzz/fuzz_sre_compile_corpus/isbn b/python_part/python/Modules/_xxtestfuzz/fuzz_sre_compile_corpus/isbn new file mode 100755 index 0000000000000000000000000000000000000000..cce8919e7285ce1175314a33e56400a5fe8c4de4 --- /dev/null +++ b/python_part/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_part/python/Modules/_xxtestfuzz/fuzz_sre_compile_corpus/phone_number b/python_part/python/Modules/_xxtestfuzz/fuzz_sre_compile_corpus/phone_number new file mode 100755 index 0000000000000000000000000000000000000000..1e2efc51103be063e74d5e93a2dac8343efaaa98 --- /dev/null +++ b/python_part/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_part/python/Modules/_xxtestfuzz/fuzz_tests.txt b/python_part/python/Modules/_xxtestfuzz/fuzz_tests.txt new file mode 100755 index 0000000000000000000000000000000000000000..9d330a668ee88b6fe22c5cb2ab9ae3604f38dd54 --- /dev/null +++ b/python_part/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_part/python/Modules/_xxtestfuzz/fuzzer.c b/python_part/python/Modules/_xxtestfuzz/fuzzer.c new file mode 100755 index 0000000000000000000000000000000000000000..1821eb2a0f017b1765460473ad9698d60138f5b6 --- /dev/null +++ b/python_part/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_part/python/Modules/addrinfo.h b/python_part/python/Modules/addrinfo.h new file mode 100755 index 0000000000000000000000000000000000000000..c3c86248dd436044bac68a6b7c78816840f02ed3 --- /dev/null +++ b/python_part/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_part/python/Modules/arraymodule.c b/python_part/python/Modules/arraymodule.c new file mode 100755 index 0000000000000000000000000000000000000000..abcdd1e8a6e53e77f81e05d472698b597e38f81d --- /dev/null +++ b/python_part/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_part/python/Modules/atexitmodule.c b/python_part/python/Modules/atexitmodule.c new file mode 100755 index 0000000000000000000000000000000000000000..1d6d6e53cfbfbe8bb7b312bc7f253095dec67511 --- /dev/null +++ b/python_part/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_part/python/Modules/audioop.c b/python_part/python/Modules/audioop.c new file mode 100755 index 0000000000000000000000000000000000000000..f4fdeb23ffa95a2c7abc0dd24dba513b752c6608 --- /dev/null +++ b/python_part/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_part/python/Modules/binascii.c b/python_part/python/Modules/binascii.c new file mode 100755 index 0000000000000000000000000000000000000000..1c7dc35882dee6ddc5beafdad35f2517ad2a0a73 --- /dev/null +++ b/python_part/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_part/python/Modules/cjkcodecs/README b/python_part/python/Modules/cjkcodecs/README new file mode 100755 index 0000000000000000000000000000000000000000..b2370bc298f771090fb947c036887d530147a487 --- /dev/null +++ b/python_part/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_part/python/Modules/cjkcodecs/_codecs_cn.c b/python_part/python/Modules/cjkcodecs/_codecs_cn.c new file mode 100755 index 0000000000000000000000000000000000000000..8a62f7e257c6b19c6116f3e396772a50fe689422 --- /dev/null +++ b/python_part/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_part/python/Modules/cjkcodecs/_codecs_hk.c b/python_part/python/Modules/cjkcodecs/_codecs_hk.c new file mode 100755 index 0000000000000000000000000000000000000000..4f21569a0ce73fc9c26baf53e85e906ea413dccc --- /dev/null +++ b/python_part/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_part/python/Modules/cjkcodecs/_codecs_iso2022.c b/python_part/python/Modules/cjkcodecs/_codecs_iso2022.c new file mode 100755 index 0000000000000000000000000000000000000000..7394cf67e0e7dd561f4c7c99d101ce5768fcec52 --- /dev/null +++ b/python_part/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_part/python/Modules/cjkcodecs/_codecs_jp.c b/python_part/python/Modules/cjkcodecs/_codecs_jp.c new file mode 100755 index 0000000000000000000000000000000000000000..3a332953b957cbdd968d8d293a6ed4a1afa47905 --- /dev/null +++ b/python_part/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_part/python/Modules/cjkcodecs/_codecs_kr.c b/python_part/python/Modules/cjkcodecs/_codecs_kr.c new file mode 100755 index 0000000000000000000000000000000000000000..6d6acb5c4be4b50df2bc583fc7689564fef07964 --- /dev/null +++ b/python_part/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_part/python/Modules/cjkcodecs/_codecs_tw.c b/python_part/python/Modules/cjkcodecs/_codecs_tw.c new file mode 100755 index 0000000000000000000000000000000000000000..722b26b128a708c13d92ff1252d66588479c71d4 --- /dev/null +++ b/python_part/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_part/python/Modules/cjkcodecs/alg_jisx0201.h b/python_part/python/Modules/cjkcodecs/alg_jisx0201.h new file mode 100755 index 0000000000000000000000000000000000000000..3034b5ab9df7e3f48b5e718cd0d967c08af091bc --- /dev/null +++ b/python_part/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_part/python/Modules/cjkcodecs/cjkcodecs.h b/python_part/python/Modules/cjkcodecs/cjkcodecs.h new file mode 100755 index 0000000000000000000000000000000000000000..b67f3482faf8dac7d3ea8986a586ea1cc88d47cd --- /dev/null +++ b/python_part/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_part/python/Modules/cjkcodecs/clinic/multibytecodec.c.h b/python_part/python/Modules/cjkcodecs/clinic/multibytecodec.c.h new file mode 100755 index 0000000000000000000000000000000000000000..5ddbbe221b98b97a55f04fb13f87b6dc5d793783 --- /dev/null +++ b/python_part/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_part/python/Modules/cjkcodecs/emu_jisx0213_2000.h b/python_part/python/Modules/cjkcodecs/emu_jisx0213_2000.h new file mode 100755 index 0000000000000000000000000000000000000000..a5d5a7063d37e6f23716d6d866fcd85bccf6784d --- /dev/null +++ b/python_part/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_part/python/Modules/cjkcodecs/mappings_cn.h b/python_part/python/Modules/cjkcodecs/mappings_cn.h new file mode 100755 index 0000000000000000000000000000000000000000..1f8c299d24239ace6efed8f642b6a9f14bb95b59 --- /dev/null +++ b/python_part/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_part/python/Modules/cjkcodecs/mappings_hk.h b/python_part/python/Modules/cjkcodecs/mappings_hk.h new file mode 100755 index 0000000000000000000000000000000000000000..1b1d70e7c1750c7d08e81610164212733ef16f86 --- /dev/null +++ b/python_part/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_part/python/Modules/cjkcodecs/mappings_jisx0213_pair.h b/python_part/python/Modules/cjkcodecs/mappings_jisx0213_pair.h new file mode 100755 index 0000000000000000000000000000000000000000..729e4bcbe66f13c4212365b37133cd9bfe291132 --- /dev/null +++ b/python_part/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_part/python/Modules/cjkcodecs/mappings_jp.h b/python_part/python/Modules/cjkcodecs/mappings_jp.h new file mode 100755 index 0000000000000000000000000000000000000000..c6dae3daa7df26e6efe4d82e2e1740d3c7c7fcc3 --- /dev/null +++ b/python_part/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_part/python/Modules/cjkcodecs/mappings_kr.h b/python_part/python/Modules/cjkcodecs/mappings_kr.h new file mode 100755 index 0000000000000000000000000000000000000000..7e6fdd2701bddf68d2f5163f3522f1382e094bfe --- /dev/null +++ b/python_part/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_part/python/Modules/cjkcodecs/mappings_tw.h b/python_part/python/Modules/cjkcodecs/mappings_tw.h new file mode 100755 index 0000000000000000000000000000000000000000..ec3f9f7468e41b1d5f4aa8bfe4dbfd4bfa2b64be --- /dev/null +++ b/python_part/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_part/python/Modules/cjkcodecs/multibytecodec.c b/python_part/python/Modules/cjkcodecs/multibytecodec.c new file mode 100755 index 0000000000000000000000000000000000000000..4a751f7ca55566ad0e0d2ca70cd78c688603e845 --- /dev/null +++ b/python_part/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_part/python/Modules/cjkcodecs/multibytecodec.h b/python_part/python/Modules/cjkcodecs/multibytecodec.h new file mode 100755 index 0000000000000000000000000000000000000000..6d34534ee685b1199ca5e8d269a04cf8dc8747f9 --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/_abc.c.h b/python_part/python/Modules/clinic/_abc.c.h new file mode 100755 index 0000000000000000000000000000000000000000..62c6552ba645dd34b8873539260167f920fb06d0 --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/_asynciomodule.c.h b/python_part/python/Modules/clinic/_asynciomodule.c.h new file mode 100755 index 0000000000000000000000000000000000000000..17eb77334d0a73e514eedb7951b51f7676cf0fe3 --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/_bz2module.c.h b/python_part/python/Modules/clinic/_bz2module.c.h new file mode 100755 index 0000000000000000000000000000000000000000..ac826bd9b5986fe894eb8c2ab4ea9ec14295e647 --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/_codecsmodule.c.h b/python_part/python/Modules/clinic/_codecsmodule.c.h new file mode 100755 index 0000000000000000000000000000000000000000..772c8ca538da239e5768a4c850b551ebc3af7b01 --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/_collectionsmodule.c.h b/python_part/python/Modules/clinic/_collectionsmodule.c.h new file mode 100755 index 0000000000000000000000000000000000000000..c3ba1a6698571d4af6037ca1b86263b09e5a749a --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/_contextvarsmodule.c.h b/python_part/python/Modules/clinic/_contextvarsmodule.c.h new file mode 100755 index 0000000000000000000000000000000000000000..b1885e41c355d27e2447ca8e3f4890b381411c8e --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/_cryptmodule.c.h b/python_part/python/Modules/clinic/_cryptmodule.c.h new file mode 100755 index 0000000000000000000000000000000000000000..ea91d7c130b8cdd684dfc2975ca1a08bfb587b49 --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/_curses_panel.c.h b/python_part/python/Modules/clinic/_curses_panel.c.h new file mode 100755 index 0000000000000000000000000000000000000000..9840ed86e791293a17d3f87d968155b5079112e1 --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/_cursesmodule.c.h b/python_part/python/Modules/clinic/_cursesmodule.c.h new file mode 100755 index 0000000000000000000000000000000000000000..889c2f64e1a118d3699c983d132f26cdc800c3b8 --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/_datetimemodule.c.h b/python_part/python/Modules/clinic/_datetimemodule.c.h new file mode 100755 index 0000000000000000000000000000000000000000..447036ca03814c8116b1f858103d03328a857c83 --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/_dbmmodule.c.h b/python_part/python/Modules/clinic/_dbmmodule.c.h new file mode 100755 index 0000000000000000000000000000000000000000..a7d735085068deec05edfe02031dc2b2c234b8e3 --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/_elementtree.c.h b/python_part/python/Modules/clinic/_elementtree.c.h new file mode 100755 index 0000000000000000000000000000000000000000..0bc4bb5d15ce7e1fac3bb32378f07f562dc546b3 --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/_gdbmmodule.c.h b/python_part/python/Modules/clinic/_gdbmmodule.c.h new file mode 100755 index 0000000000000000000000000000000000000000..aa37a24d3b211505542c8325e987c0cb95f31065 --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/_hashopenssl.c.h b/python_part/python/Modules/clinic/_hashopenssl.c.h new file mode 100755 index 0000000000000000000000000000000000000000..9aaea47e8328edd512f129c16809186f6b37754d --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/_heapqmodule.c.h b/python_part/python/Modules/clinic/_heapqmodule.c.h new file mode 100755 index 0000000000000000000000000000000000000000..55403706ba05ccfcdfc64d21db666cdfb49bba50 --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/_lzmamodule.c.h b/python_part/python/Modules/clinic/_lzmamodule.c.h new file mode 100755 index 0000000000000000000000000000000000000000..82ef4d517d83c59b3f1409fb537147e358ddf8a2 --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/_opcode.c.h b/python_part/python/Modules/clinic/_opcode.c.h new file mode 100755 index 0000000000000000000000000000000000000000..777701ff140954a673181ee9586a350664760e9b --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/_operator.c.h b/python_part/python/Modules/clinic/_operator.c.h new file mode 100755 index 0000000000000000000000000000000000000000..f9e353d86b4961d8b5990c3e95162ac88a5c0045 --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/_pickle.c.h b/python_part/python/Modules/clinic/_pickle.c.h new file mode 100755 index 0000000000000000000000000000000000000000..0457a433e79fb04c725975eca730fee8d5663b50 --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/_queuemodule.c.h b/python_part/python/Modules/clinic/_queuemodule.c.h new file mode 100755 index 0000000000000000000000000000000000000000..c25eacf08bc843ba143e18c384ff390abb82281e --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/_randommodule.c.h b/python_part/python/Modules/clinic/_randommodule.c.h new file mode 100755 index 0000000000000000000000000000000000000000..a467811d93b2726ed5f54548f807888685f5cbd5 --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/_sre.c.h b/python_part/python/Modules/clinic/_sre.c.h new file mode 100755 index 0000000000000000000000000000000000000000..d398a8504ba4180da237b30aad9576faab573903 --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/_ssl.c.h b/python_part/python/Modules/clinic/_ssl.c.h new file mode 100755 index 0000000000000000000000000000000000000000..ce8669ae212edb27a1adfe6cd93bce58493da7a7 --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/_statisticsmodule.c.h b/python_part/python/Modules/clinic/_statisticsmodule.c.h new file mode 100755 index 0000000000000000000000000000000000000000..5ff01efddcde893e2e9fb861a6d3f2e529895c71 --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/_struct.c.h b/python_part/python/Modules/clinic/_struct.c.h new file mode 100755 index 0000000000000000000000000000000000000000..36c4b4046cd73983400339c888085cd580949d69 --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/_tkinter.c.h b/python_part/python/Modules/clinic/_tkinter.c.h new file mode 100755 index 0000000000000000000000000000000000000000..73c3faeaf962e0adebbe9a9fc37ef1b6443484cf --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/_tracemalloc.c.h b/python_part/python/Modules/clinic/_tracemalloc.c.h new file mode 100755 index 0000000000000000000000000000000000000000..68fafdc3833d2e3a3da6921849159725d264e1a7 --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/_weakref.c.h b/python_part/python/Modules/clinic/_weakref.c.h new file mode 100755 index 0000000000000000000000000000000000000000..c3a908fa6a139e5ab84399b0a7089dbe8351ed73 --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/_winapi.c.h b/python_part/python/Modules/clinic/_winapi.c.h new file mode 100755 index 0000000000000000000000000000000000000000..e21f2bc2b6fd6f6fd44186a0a5af258f9477145d --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/arraymodule.c.h b/python_part/python/Modules/clinic/arraymodule.c.h new file mode 100755 index 0000000000000000000000000000000000000000..33f82d4da8b6c90cf34ff5fd1bd2d9fbb90804af --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/audioop.c.h b/python_part/python/Modules/clinic/audioop.c.h new file mode 100755 index 0000000000000000000000000000000000000000..8745533eeb629dc3900f4a4e195adbfff4a2d9c7 --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/binascii.c.h b/python_part/python/Modules/clinic/binascii.c.h new file mode 100755 index 0000000000000000000000000000000000000000..82942f08a68681fe98f4b8d7735ab9247373c061 --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/cmathmodule.c.h b/python_part/python/Modules/clinic/cmathmodule.c.h new file mode 100755 index 0000000000000000000000000000000000000000..81a8437c3a7d17936bc9a5ed29c4d3ee3f6e8045 --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/fcntlmodule.c.h b/python_part/python/Modules/clinic/fcntlmodule.c.h new file mode 100755 index 0000000000000000000000000000000000000000..024a44cfbf8bc60ffb7052a95e12982fcfd1b6f9 --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/gcmodule.c.h b/python_part/python/Modules/clinic/gcmodule.c.h new file mode 100755 index 0000000000000000000000000000000000000000..22d2aa4a87bcd0a4fbf1b909b20e11f95d645228 --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/grpmodule.c.h b/python_part/python/Modules/clinic/grpmodule.c.h new file mode 100755 index 0000000000000000000000000000000000000000..2e2690ad8d3f117f6b26d358a0ec5c15e6d9b0f6 --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/itertoolsmodule.c.h b/python_part/python/Modules/clinic/itertoolsmodule.c.h new file mode 100755 index 0000000000000000000000000000000000000000..20594b0fed4c34a5ca86e155beff973039ba9776 --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/mathmodule.c.h b/python_part/python/Modules/clinic/mathmodule.c.h new file mode 100755 index 0000000000000000000000000000000000000000..95d68ee55ae5bab4461f6b0344ac82afcec7866f --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/md5module.c.h b/python_part/python/Modules/clinic/md5module.c.h new file mode 100755 index 0000000000000000000000000000000000000000..12484cc0e3dd88c5a0df39359c3b21af624bf38c --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/posixmodule.c.h b/python_part/python/Modules/clinic/posixmodule.c.h new file mode 100755 index 0000000000000000000000000000000000000000..042eb4bd3f241a479971e64721a3281512134bdc --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/pwdmodule.c.h b/python_part/python/Modules/clinic/pwdmodule.c.h new file mode 100755 index 0000000000000000000000000000000000000000..cb83062495dcf93c95a29ecbdd6eafc6e709553d --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/pyexpat.c.h b/python_part/python/Modules/clinic/pyexpat.c.h new file mode 100755 index 0000000000000000000000000000000000000000..ee5907ca7e447bcd7261ef5d84175765059b87f8 --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/resource.c.h b/python_part/python/Modules/clinic/resource.c.h new file mode 100755 index 0000000000000000000000000000000000000000..80efb714bb6b642f83a760c1d2a4b7d0ea3b5cd7 --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/selectmodule.c.h b/python_part/python/Modules/clinic/selectmodule.c.h new file mode 100755 index 0000000000000000000000000000000000000000..a9e14840710c7a1f441d4fc1f208c5542553401e --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/sha1module.c.h b/python_part/python/Modules/clinic/sha1module.c.h new file mode 100755 index 0000000000000000000000000000000000000000..001c6af73782effa0c2f4718e81e255cd4a179f7 --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/sha256module.c.h b/python_part/python/Modules/clinic/sha256module.c.h new file mode 100755 index 0000000000000000000000000000000000000000..658abb15cf309dfdc0b2ce694b76a0bc0b0acaff --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/sha512module.c.h b/python_part/python/Modules/clinic/sha512module.c.h new file mode 100755 index 0000000000000000000000000000000000000000..459a9341cfc5bc48d0d956571f016cde3442cadd --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/signalmodule.c.h b/python_part/python/Modules/clinic/signalmodule.c.h new file mode 100755 index 0000000000000000000000000000000000000000..3cb1db14878c5670192374eac3fa0dfa2b280066 --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/spwdmodule.c.h b/python_part/python/Modules/clinic/spwdmodule.c.h new file mode 100755 index 0000000000000000000000000000000000000000..411d2344e18fbababfdc52babcd0997a93b58149 --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/symtablemodule.c.h b/python_part/python/Modules/clinic/symtablemodule.c.h new file mode 100755 index 0000000000000000000000000000000000000000..4a17f130ac97bc19739c308ea833e7778df75570 --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/unicodedata.c.h b/python_part/python/Modules/clinic/unicodedata.c.h new file mode 100755 index 0000000000000000000000000000000000000000..4251db2edc7b96b62d871c1ccc37acfa1dd9a0a7 --- /dev/null +++ b/python_part/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_part/python/Modules/clinic/zlibmodule.c.h b/python_part/python/Modules/clinic/zlibmodule.c.h new file mode 100755 index 0000000000000000000000000000000000000000..77ea04a353bf141e3f4a176f0a736fcfa5fb0217 --- /dev/null +++ b/python_part/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_part/python/Modules/cmathmodule.c b/python_part/python/Modules/cmathmodule.c new file mode 100755 index 0000000000000000000000000000000000000000..02c09bbea48ac3b63246d6ac4ccf1605228cf148 --- /dev/null +++ b/python_part/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_part/python/Modules/config.c b/python_part/python/Modules/config.c new file mode 100755 index 0000000000000000000000000000000000000000..68a07bf946319e5eec06fcfbce26c477eaefe5de --- /dev/null +++ b/python_part/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_part/python/Modules/config.c.in b/python_part/python/Modules/config.c.in new file mode 100755 index 0000000000000000000000000000000000000000..d69e8e88b0ca458b31c247d98f3747f2f11ebe67 --- /dev/null +++ b/python_part/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_part/python/Modules/errnomodule.c b/python_part/python/Modules/errnomodule.c new file mode 100755 index 0000000000000000000000000000000000000000..06ed53a64dbdc1835cd53fb4d473430c3fdfb9dd --- /dev/null +++ b/python_part/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_part/python/Modules/expat/COPYING b/python_part/python/Modules/expat/COPYING new file mode 100755 index 0000000000000000000000000000000000000000..8d288f0f28fddd7bb86d3b224de2bff642298d9c --- /dev/null +++ b/python_part/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_part/python/Modules/expat/ascii.h b/python_part/python/Modules/expat/ascii.h new file mode 100755 index 0000000000000000000000000000000000000000..c3587e57332bff8a0089f60091a987200657b546 --- /dev/null +++ b/python_part/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_part/python/Modules/expat/asciitab.h b/python_part/python/Modules/expat/asciitab.h new file mode 100755 index 0000000000000000000000000000000000000000..63b1d1b4482efa86406a54dd421e59f04f8c725f --- /dev/null +++ b/python_part/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_part/python/Modules/expat/expat.h b/python_part/python/Modules/expat/expat.h new file mode 100755 index 0000000000000000000000000000000000000000..6c8eb1fda4a30c3ea1bc4893f4865d79f74325f1 --- /dev/null +++ b/python_part/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_part/python/Modules/expat/expat_config.h b/python_part/python/Modules/expat/expat_config.h new file mode 100755 index 0000000000000000000000000000000000000000..afbedd011f660ff96c10f025a40e102c98363906 --- /dev/null +++ b/python_part/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_part/python/Modules/expat/expat_external.h b/python_part/python/Modules/expat/expat_external.h new file mode 100755 index 0000000000000000000000000000000000000000..f2b75dda8e27987444b24e831e232a61e7f6318e --- /dev/null +++ b/python_part/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_part/python/Modules/expat/iasciitab.h b/python_part/python/Modules/expat/iasciitab.h new file mode 100755 index 0000000000000000000000000000000000000000..ea97cfcf678e06d3f6030892a8ee04acbb310d7e --- /dev/null +++ b/python_part/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_part/python/Modules/expat/internal.h b/python_part/python/Modules/expat/internal.h new file mode 100755 index 0000000000000000000000000000000000000000..60913dab762f8f06312259271a7c45b8cc4f51fe --- /dev/null +++ b/python_part/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_part/python/Modules/expat/latin1tab.h b/python_part/python/Modules/expat/latin1tab.h new file mode 100755 index 0000000000000000000000000000000000000000..6f916041355a86ed3a6ce0ca09487a7c8bfa7ae6 --- /dev/null +++ b/python_part/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_part/python/Modules/expat/nametab.h b/python_part/python/Modules/expat/nametab.h new file mode 100755 index 0000000000000000000000000000000000000000..3681df348eebd66dabf75a77039c8c4a885c3a46 --- /dev/null +++ b/python_part/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_part/python/Modules/expat/pyexpatns.h b/python_part/python/Modules/expat/pyexpatns.h new file mode 100755 index 0000000000000000000000000000000000000000..963cc18e4dd04d7a93d7a2bdac9943904ef80bf9 --- /dev/null +++ b/python_part/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_part/python/Modules/expat/siphash.h b/python_part/python/Modules/expat/siphash.h new file mode 100755 index 0000000000000000000000000000000000000000..bfee65a332f1bfeca053116925099ba7064f28d4 --- /dev/null +++ b/python_part/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_part/python/Modules/expat/utf8tab.h b/python_part/python/Modules/expat/utf8tab.h new file mode 100755 index 0000000000000000000000000000000000000000..a22986acbb9526b34c33a4ffa8a0f74c5ef36d15 --- /dev/null +++ b/python_part/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_part/python/Modules/expat/winconfig.h b/python_part/python/Modules/expat/winconfig.h new file mode 100755 index 0000000000000000000000000000000000000000..562a4a82dc1d638b2cc84282ee9be29de00fc801 --- /dev/null +++ b/python_part/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_part/python/Modules/expat/xmlparse.c b/python_part/python/Modules/expat/xmlparse.c new file mode 100755 index 0000000000000000000000000000000000000000..077167ee94263601f826043e4c79ca8f3a246c3d --- /dev/null +++ b/python_part/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_part/python/Modules/expat/xmlrole.c b/python_part/python/Modules/expat/xmlrole.c new file mode 100755 index 0000000000000000000000000000000000000000..4d3e3e86e9e864dd64f9f184c9467b05659d299e --- /dev/null +++ b/python_part/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_part/python/Modules/expat/xmlrole.h b/python_part/python/Modules/expat/xmlrole.h new file mode 100755 index 0000000000000000000000000000000000000000..036aba64fd29c6950b7007d62c16448f71ab732b --- /dev/null +++ b/python_part/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_part/python/Modules/expat/xmltok.c b/python_part/python/Modules/expat/xmltok.c new file mode 100755 index 0000000000000000000000000000000000000000..7e2ed10444ea07998a7e24f1a9fe0b1b78d60cc4 --- /dev/null +++ b/python_part/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_part/python/Modules/expat/xmltok.h b/python_part/python/Modules/expat/xmltok.h new file mode 100755 index 0000000000000000000000000000000000000000..2adbf5307befaedec56ade9cf65dbca3734b284e --- /dev/null +++ b/python_part/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_part/python/Modules/expat/xmltok_impl.c b/python_part/python/Modules/expat/xmltok_impl.c new file mode 100755 index 0000000000000000000000000000000000000000..460ae9f12c6792fb4312530bcbcb56eb7fcf41e3 --- /dev/null +++ b/python_part/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_part/python/Modules/expat/xmltok_impl.h b/python_part/python/Modules/expat/xmltok_impl.h new file mode 100755 index 0000000000000000000000000000000000000000..e925dbc7e2c8337749ad3eeab84095e60e660fba --- /dev/null +++ b/python_part/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_part/python/Modules/expat/xmltok_ns.c b/python_part/python/Modules/expat/xmltok_ns.c new file mode 100755 index 0000000000000000000000000000000000000000..919c74e9f97fe8129aacc514217c94f89dd86109 --- /dev/null +++ b/python_part/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_part/python/Modules/faulthandler.c b/python_part/python/Modules/faulthandler.c new file mode 100755 index 0000000000000000000000000000000000000000..230cde4934fd437eb6f30880ee9d5fe3ff2af1af --- /dev/null +++ b/python_part/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_part/python/Modules/fcntlmodule.c b/python_part/python/Modules/fcntlmodule.c new file mode 100755 index 0000000000000000000000000000000000000000..a7d2193022e982b0b1712346166c11730fd135c6 --- /dev/null +++ b/python_part/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_part/python/Modules/gc_weakref.txt b/python_part/python/Modules/gc_weakref.txt new file mode 100755 index 0000000000000000000000000000000000000000..2f18402c02a51d9c8e4444fc69058c90bc9ac2c2 --- /dev/null +++ b/python_part/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_part/python/Modules/gcmodule.c b/python_part/python/Modules/gcmodule.c new file mode 100755 index 0000000000000000000000000000000000000000..81737251b725e2139690cb0685537185af6757fb --- /dev/null +++ b/python_part/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_part/python/Modules/getaddrinfo.c b/python_part/python/Modules/getaddrinfo.c new file mode 100755 index 0000000000000000000000000000000000000000..d33a100054bae2faf995705d7ceb8e8c81773a47 --- /dev/null +++ b/python_part/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_part/python/Modules/getbuildinfo.c b/python_part/python/Modules/getbuildinfo.c new file mode 100755 index 0000000000000000000000000000000000000000..330f6ed45065f9dd9cffab6da74d8b1451fc07a5 --- /dev/null +++ b/python_part/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_part/python/Modules/getnameinfo.c b/python_part/python/Modules/getnameinfo.c new file mode 100755 index 0000000000000000000000000000000000000000..dc13a814ec763608ad5d31178acc1e352dcc13e7 --- /dev/null +++ b/python_part/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_part/python/Modules/getpath.c b/python_part/python/Modules/getpath.c new file mode 100755 index 0000000000000000000000000000000000000000..2c92fc0bdb76341a3f1e06799039f26d733e91e1 --- /dev/null +++ b/python_part/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_part/python/Modules/grpmodule.c b/python_part/python/Modules/grpmodule.c new file mode 100755 index 0000000000000000000000000000000000000000..ab766b9850936dd9e7b292b157060cfc570aa893 --- /dev/null +++ b/python_part/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_part/python/Modules/hashlib.h b/python_part/python/Modules/hashlib.h new file mode 100755 index 0000000000000000000000000000000000000000..978593e2f1a0c2f795c3c8710629f76c3351217d --- /dev/null +++ b/python_part/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_part/python/Modules/hashtable.c b/python_part/python/Modules/hashtable.c new file mode 100755 index 0000000000000000000000000000000000000000..4a36a1e71cdd05518403662cc3985abc666b911c --- /dev/null +++ b/python_part/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_part/python/Modules/hashtable.h b/python_part/python/Modules/hashtable.h new file mode 100755 index 0000000000000000000000000000000000000000..dbec23d28518729a8d5632449f884ccf86d29447 --- /dev/null +++ b/python_part/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_part/python/Modules/itertoolsmodule.c b/python_part/python/Modules/itertoolsmodule.c new file mode 100755 index 0000000000000000000000000000000000000000..eb04c26beb81d31d5971aa6827181051c08ef370 --- /dev/null +++ b/python_part/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_part/python/Modules/ld_so_aix b/python_part/python/Modules/ld_so_aix new file mode 100755 index 0000000000000000000000000000000000000000..1d6decbf4f77fa6cb7cbcf79033125059c41ed7e --- /dev/null +++ b/python_part/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_part/python/Modules/ld_so_aix.in b/python_part/python/Modules/ld_so_aix.in new file mode 100755 index 0000000000000000000000000000000000000000..f4eab40b6b82193c13822adafe3185ddb6bd0ac0 --- /dev/null +++ b/python_part/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_part/python/Modules/main.c b/python_part/python/Modules/main.c new file mode 100755 index 0000000000000000000000000000000000000000..ea6250e28c1b8b9ffd2e5b23991c9ed251c6e01a --- /dev/null +++ b/python_part/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_part/python/Modules/makesetup b/python_part/python/Modules/makesetup new file mode 100755 index 0000000000000000000000000000000000000000..fefe3fd129ee3b2440714aeaec91dd075e92699a --- /dev/null +++ b/python_part/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_part/python/Modules/makexp_aix b/python_part/python/Modules/makexp_aix new file mode 100755 index 0000000000000000000000000000000000000000..cb349c2875739622664ae7743ae5fbba4a9da2ed --- /dev/null +++ b/python_part/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_part/python/Modules/mathmodule.c b/python_part/python/Modules/mathmodule.c new file mode 100755 index 0000000000000000000000000000000000000000..b78fcedd03de5fd2c0cda356c39ef0c89da6e9d1 --- /dev/null +++ b/python_part/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_part/python/Modules/md5module.c b/python_part/python/Modules/md5module.c new file mode 100755 index 0000000000000000000000000000000000000000..64fab8081b5dc153e4cbc91a2a074633177f7a02 --- /dev/null +++ b/python_part/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_part/python/Modules/mmapmodule.c b/python_part/python/Modules/mmapmodule.c new file mode 100755 index 0000000000000000000000000000000000000000..18758861a62e9c0d8c4a81cdfc5205a96125ffed --- /dev/null +++ b/python_part/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_part/python/Modules/nismodule.c b/python_part/python/Modules/nismodule.c new file mode 100755 index 0000000000000000000000000000000000000000..e1fa45c4f6f28aa8a0a203497ef7bb3506f6aa01 --- /dev/null +++ b/python_part/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_part/python/Modules/ossaudiodev.c b/python_part/python/Modules/ossaudiodev.c new file mode 100755 index 0000000000000000000000000000000000000000..f7712d97c2d724f1c1f95e783d7a79fac4f88f56 --- /dev/null +++ b/python_part/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_part/python/Modules/overlapped.c b/python_part/python/Modules/overlapped.c new file mode 100755 index 0000000000000000000000000000000000000000..2b57f69e7f01b4dc4df344fa3a93d48e35ce287a --- /dev/null +++ b/python_part/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_part/python/Modules/parsermodule.c b/python_part/python/Modules/parsermodule.c new file mode 100755 index 0000000000000000000000000000000000000000..079d00f32aa6cd3bbed2bcd12dc41d37e7c4e532 --- /dev/null +++ b/python_part/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_part/python/Modules/posixmodule.c b/python_part/python/Modules/posixmodule.c new file mode 100755 index 0000000000000000000000000000000000000000..d7edabe5da08d1b9966b2c58450985d77e559c0a --- /dev/null +++ b/python_part/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_part/python/Modules/posixmodule.h b/python_part/python/Modules/posixmodule.h new file mode 100755 index 0000000000000000000000000000000000000000..1e00562abc3370eb44631b6c065f47e2d995fdd7 --- /dev/null +++ b/python_part/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_part/python/Modules/pwdmodule.c b/python_part/python/Modules/pwdmodule.c new file mode 100755 index 0000000000000000000000000000000000000000..e0232b8d589baa844f40b21ceda194ac1c20871e --- /dev/null +++ b/python_part/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_part/python/Modules/pyexpat.c b/python_part/python/Modules/pyexpat.c new file mode 100755 index 0000000000000000000000000000000000000000..934b58dca5a8b7f7c0c6cdb7ec94ea92e57ed15f --- /dev/null +++ b/python_part/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_part/python/Modules/readline.c b/python_part/python/Modules/readline.c new file mode 100755 index 0000000000000000000000000000000000000000..92c1de4396d6eb007324a5fc2fd15bb76bb671a7 --- /dev/null +++ b/python_part/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_part/python/Modules/resource.c b/python_part/python/Modules/resource.c new file mode 100755 index 0000000000000000000000000000000000000000..afde03c6c7e55983ff3f8fa615e8d840a453de2b --- /dev/null +++ b/python_part/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_part/python/Modules/rotatingtree.c b/python_part/python/Modules/rotatingtree.c new file mode 100755 index 0000000000000000000000000000000000000000..07e08bc3167c0a408352b8ee7a1bbf5ed66006ad --- /dev/null +++ b/python_part/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_part/python/Modules/rotatingtree.h b/python_part/python/Modules/rotatingtree.h new file mode 100755 index 0000000000000000000000000000000000000000..7b3e5fde921cb381f4548a18fc2ebd0dcdc3007b --- /dev/null +++ b/python_part/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_part/python/Modules/selectmodule.c b/python_part/python/Modules/selectmodule.c new file mode 100755 index 0000000000000000000000000000000000000000..a71b64223d049a8a48c900d4b2b9bd4794a12b3e --- /dev/null +++ b/python_part/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_part/python/Modules/sha1module.c b/python_part/python/Modules/sha1module.c new file mode 100755 index 0000000000000000000000000000000000000000..4a8dbd8539b7a14e7a4ec3ec9e39dba1f8225bc4 --- /dev/null +++ b/python_part/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_part/python/Modules/sha256module.c b/python_part/python/Modules/sha256module.c new file mode 100755 index 0000000000000000000000000000000000000000..a1c8b1a3dfb5a1112300d1454d010a54bed4380d --- /dev/null +++ b/python_part/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_part/python/Modules/sha512module.c b/python_part/python/Modules/sha512module.c new file mode 100755 index 0000000000000000000000000000000000000000..4167fd391cc4a32123f8a2b9aac1c2d685f43822 --- /dev/null +++ b/python_part/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_part/python/Modules/signalmodule.c b/python_part/python/Modules/signalmodule.c new file mode 100755 index 0000000000000000000000000000000000000000..4b855d6f3078d74e174582369f0d6a4f19842da8 --- /dev/null +++ b/python_part/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_part/python/Modules/socketmodule.c b/python_part/python/Modules/socketmodule.c new file mode 100755 index 0000000000000000000000000000000000000000..5406f8b46f243f153b8c30d6cc2d19832a04a200 --- /dev/null +++ b/python_part/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_part/python/Modules/spwdmodule.c b/python_part/python/Modules/spwdmodule.c new file mode 100755 index 0000000000000000000000000000000000000000..1601ec0f2fc4e726c248498c2315c091f497f88e --- /dev/null +++ b/python_part/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_part/python/Modules/sre.h b/python_part/python/Modules/sre.h new file mode 100755 index 0000000000000000000000000000000000000000..a7284881457c3b1865e0c9b9503cecf01a17eea9 --- /dev/null +++ b/python_part/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_part/python/Modules/sre_constants.h b/python_part/python/Modules/sre_constants.h new file mode 100755 index 0000000000000000000000000000000000000000..c8ccb32d21de6ce3669d5cf67f0352d10a92fc0d --- /dev/null +++ b/python_part/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_part/python/Modules/sre_lib.h b/python_part/python/Modules/sre_lib.h new file mode 100755 index 0000000000000000000000000000000000000000..437ab43f434a62ab5b3fdd892c52c1df24b40f32 --- /dev/null +++ b/python_part/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_part/python/Modules/symtablemodule.c b/python_part/python/Modules/symtablemodule.c new file mode 100755 index 0000000000000000000000000000000000000000..9180f185e1e8772f9d70702b5b792ec510398c5d --- /dev/null +++ b/python_part/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_part/python/Modules/syslogmodule.c b/python_part/python/Modules/syslogmodule.c new file mode 100755 index 0000000000000000000000000000000000000000..66ea2703fc84a7e8bdd5b271d4cdc1cd021ff080 --- /dev/null +++ b/python_part/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_part/python/Modules/termios.c b/python_part/python/Modules/termios.c new file mode 100755 index 0000000000000000000000000000000000000000..aee7f12c57cab5757e7c23eb06d6eeb06d6f3faa --- /dev/null +++ b/python_part/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_part/python/Modules/testcapi_long.h b/python_part/python/Modules/testcapi_long.h new file mode 100755 index 0000000000000000000000000000000000000000..6bddad7bb5d249e779fa23a44af5f9194091a37c --- /dev/null +++ b/python_part/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_part/python/Modules/timemodule.c b/python_part/python/Modules/timemodule.c new file mode 100755 index 0000000000000000000000000000000000000000..096911dacfe5ae0ee8ac70e93c6abb24b4267079 --- /dev/null +++ b/python_part/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_part/python/Modules/tkappinit.c b/python_part/python/Modules/tkappinit.c new file mode 100755 index 0000000000000000000000000000000000000000..493da65960841d066ef7b524de7ae2fe87b20d1c --- /dev/null +++ b/python_part/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_part/python/Modules/tkinter.h b/python_part/python/Modules/tkinter.h new file mode 100755 index 0000000000000000000000000000000000000000..cb5a806b0c43262a01a717b6bb9faddb83efb5d6 --- /dev/null +++ b/python_part/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_part/python/Modules/unicodedata.c b/python_part/python/Modules/unicodedata.c new file mode 100755 index 0000000000000000000000000000000000000000..5e8ba602d6684825f2f97497ef8c310fe781fd68 --- /dev/null +++ b/python_part/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_part/python/Modules/unicodedata_db.h b/python_part/python/Modules/unicodedata_db.h new file mode 100755 index 0000000000000000000000000000000000000000..286287d047ca983822b050f82d4cb88ba9251a6d --- /dev/null +++ b/python_part/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_part/python/Modules/unicodename_db.h b/python_part/python/Modules/unicodename_db.h new file mode 100755 index 0000000000000000000000000000000000000000..60521106b18963a941d000858fc853888ead281f --- /dev/null +++ b/python_part/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_part/python/Modules/winreparse.h b/python_part/python/Modules/winreparse.h new file mode 100755 index 0000000000000000000000000000000000000000..f06f701f999ca68733d6f197140fac162a725d20 --- /dev/null +++ b/python_part/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_part/python/Modules/xxlimited.c b/python_part/python/Modules/xxlimited.c new file mode 100755 index 0000000000000000000000000000000000000000..ffc04e0310e392780625b13d62a850aaa66078e5 --- /dev/null +++ b/python_part/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_part/python/Modules/xxmodule.c b/python_part/python/Modules/xxmodule.c new file mode 100755 index 0000000000000000000000000000000000000000..0250031d722d3a97e2d501fcca7a716080d6a877 --- /dev/null +++ b/python_part/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_part/python/Modules/xxsubtype.c b/python_part/python/Modules/xxsubtype.c new file mode 100755 index 0000000000000000000000000000000000000000..031005d36e20f2a519e4675804cce284bd7443ac --- /dev/null +++ b/python_part/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_part/python/Modules/zlibmodule.c b/python_part/python/Modules/zlibmodule.c new file mode 100755 index 0000000000000000000000000000000000000000..d6b6b01d89a17490593be6ffa0cf3f4fecdfe792 --- /dev/null +++ b/python_part/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_part/python/Objects/README b/python_part/python/Objects/README new file mode 100755 index 0000000000000000000000000000000000000000..854b103f7bd606aea86b1d232f9b04d81c384f64 --- /dev/null +++ b/python_part/python/Objects/README @@ -0,0 +1 @@ +Source files for various builtin objects diff --git a/python_part/python/Objects/abstract.c b/python_part/python/Objects/abstract.c new file mode 100755 index 0000000000000000000000000000000000000000..9c42d817b42111fb74a5b166cc2f0cc8b8403f6d --- /dev/null +++ b/python_part/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_part/python/Objects/accu.c b/python_part/python/Objects/accu.c new file mode 100755 index 0000000000000000000000000000000000000000..c8b5d382e388b76fd6ead7b7c25ea3a0dde11b1d --- /dev/null +++ b/python_part/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_part/python/Objects/boolobject.c b/python_part/python/Objects/boolobject.c new file mode 100755 index 0000000000000000000000000000000000000000..720835b98aa65ee51b74eda35926cf53c90cf1ad --- /dev/null +++ b/python_part/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_part/python/Objects/bytearrayobject.c b/python_part/python/Objects/bytearrayobject.c new file mode 100755 index 0000000000000000000000000000000000000000..9812afd6f2c34e1ef2695b6afc03aaba9ed5bf4f --- /dev/null +++ b/python_part/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_part/python/Objects/bytes_methods.c b/python_part/python/Objects/bytes_methods.c new file mode 100755 index 0000000000000000000000000000000000000000..db030be4fe7561600e8c968759e073981bc8d776 --- /dev/null +++ b/python_part/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_part/python/Objects/bytesobject.c b/python_part/python/Objects/bytesobject.c new file mode 100755 index 0000000000000000000000000000000000000000..feeabcb8b4c7ad330947ca46a50b955ba8d8236f --- /dev/null +++ b/python_part/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_part/python/Objects/call.c b/python_part/python/Objects/call.c new file mode 100755 index 0000000000000000000000000000000000000000..9672be01ed05904ca4b5b786defaed8082a37bac --- /dev/null +++ b/python_part/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_part/python/Objects/capsule.c b/python_part/python/Objects/capsule.c new file mode 100755 index 0000000000000000000000000000000000000000..599893a320dba6b4e20a06761c77350a3e11adb7 --- /dev/null +++ b/python_part/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_part/python/Objects/cellobject.c b/python_part/python/Objects/cellobject.c new file mode 100755 index 0000000000000000000000000000000000000000..911cf527a43485cabebc92b65e54feb72f1f3746 --- /dev/null +++ b/python_part/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_part/python/Objects/classobject.c b/python_part/python/Objects/classobject.c new file mode 100755 index 0000000000000000000000000000000000000000..12bb836cb716c0be93f0e3fde2dade887c3c6bc6 --- /dev/null +++ b/python_part/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_part/python/Objects/clinic/bytearrayobject.c.h b/python_part/python/Objects/clinic/bytearrayobject.c.h new file mode 100755 index 0000000000000000000000000000000000000000..05577077a5f8d4485907ae58d5ad2ef61a562f46 --- /dev/null +++ b/python_part/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_part/python/Objects/clinic/bytesobject.c.h b/python_part/python/Objects/clinic/bytesobject.c.h new file mode 100755 index 0000000000000000000000000000000000000000..22024ab155c8ecd2cff84e08295461b6300e5c73 --- /dev/null +++ b/python_part/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_part/python/Objects/clinic/codeobject.c.h b/python_part/python/Objects/clinic/codeobject.c.h new file mode 100755 index 0000000000000000000000000000000000000000..1dd82278cf3d52cd7320447e84fa037ecbfed9c8 --- /dev/null +++ b/python_part/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_part/python/Objects/clinic/complexobject.c.h b/python_part/python/Objects/clinic/complexobject.c.h new file mode 100755 index 0000000000000000000000000000000000000000..8caa910d037dae3859ce6ba0b5cbeba6023f994e --- /dev/null +++ b/python_part/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_part/python/Objects/clinic/descrobject.c.h b/python_part/python/Objects/clinic/descrobject.c.h new file mode 100755 index 0000000000000000000000000000000000000000..d248b91bf48da2784a110067f85f1a21c69535b0 --- /dev/null +++ b/python_part/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_part/python/Objects/clinic/dictobject.c.h b/python_part/python/Objects/clinic/dictobject.c.h new file mode 100755 index 0000000000000000000000000000000000000000..8d5493330835e836408b47b96bad02849a809d32 --- /dev/null +++ b/python_part/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_part/python/Objects/clinic/enumobject.c.h b/python_part/python/Objects/clinic/enumobject.c.h new file mode 100755 index 0000000000000000000000000000000000000000..09d4c87e155f47229d3b9382aeaabff64cdfc66c --- /dev/null +++ b/python_part/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_part/python/Objects/clinic/floatobject.c.h b/python_part/python/Objects/clinic/floatobject.c.h new file mode 100755 index 0000000000000000000000000000000000000000..b684ba0ef27aaf35bdfc8bb1748d27e7b868b684 --- /dev/null +++ b/python_part/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_part/python/Objects/clinic/funcobject.c.h b/python_part/python/Objects/clinic/funcobject.c.h new file mode 100755 index 0000000000000000000000000000000000000000..17fb13fe085af3b0098b761cdf3b87c81bb6d58f --- /dev/null +++ b/python_part/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_part/python/Objects/clinic/listobject.c.h b/python_part/python/Objects/clinic/listobject.c.h new file mode 100755 index 0000000000000000000000000000000000000000..57f0a48eb0838b18ada5dc60a8e15a05676c265d --- /dev/null +++ b/python_part/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_part/python/Objects/clinic/longobject.c.h b/python_part/python/Objects/clinic/longobject.c.h new file mode 100755 index 0000000000000000000000000000000000000000..27e8dfe935b6e172dcf598fd10852d4eeaed393a --- /dev/null +++ b/python_part/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_part/python/Objects/clinic/memoryobject.c.h b/python_part/python/Objects/clinic/memoryobject.c.h new file mode 100755 index 0000000000000000000000000000000000000000..75ac2011261fa0291033613432f58beee31192bb --- /dev/null +++ b/python_part/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_part/python/Objects/clinic/moduleobject.c.h b/python_part/python/Objects/clinic/moduleobject.c.h new file mode 100755 index 0000000000000000000000000000000000000000..c1534eaee258868b66a811cbea0d2b01880dcb3c --- /dev/null +++ b/python_part/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_part/python/Objects/clinic/odictobject.c.h b/python_part/python/Objects/clinic/odictobject.c.h new file mode 100755 index 0000000000000000000000000000000000000000..f43bc14ce1b623fc7c06c5b3314bb0478e2855c3 --- /dev/null +++ b/python_part/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_part/python/Objects/clinic/structseq.c.h b/python_part/python/Objects/clinic/structseq.c.h new file mode 100755 index 0000000000000000000000000000000000000000..b3b4836543d05f6a861d704576a0dc4b576d87b4 --- /dev/null +++ b/python_part/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_part/python/Objects/clinic/tupleobject.c.h b/python_part/python/Objects/clinic/tupleobject.c.h new file mode 100755 index 0000000000000000000000000000000000000000..fe2fae42eeafc0c78069bbce602ca01f19dd580d --- /dev/null +++ b/python_part/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_part/python/Objects/clinic/typeobject.c.h b/python_part/python/Objects/clinic/typeobject.c.h new file mode 100755 index 0000000000000000000000000000000000000000..357eb44b12b8a14923caa6a6d61c129ca6d753fa --- /dev/null +++ b/python_part/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_part/python/Objects/clinic/unicodeobject.c.h b/python_part/python/Objects/clinic/unicodeobject.c.h new file mode 100755 index 0000000000000000000000000000000000000000..0d134064bab0917aaff72bc5dd8353487c4e988d --- /dev/null +++ b/python_part/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_part/python/Objects/codeobject.c b/python_part/python/Objects/codeobject.c new file mode 100755 index 0000000000000000000000000000000000000000..522e1a9f2a41956089f535efc84e11e771126407 --- /dev/null +++ b/python_part/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_part/python/Objects/complexobject.c b/python_part/python/Objects/complexobject.c new file mode 100755 index 0000000000000000000000000000000000000000..e01409b971b0e16a73ae791e0d4467c3aa856bd3 --- /dev/null +++ b/python_part/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_part/python/Objects/descrobject.c b/python_part/python/Objects/descrobject.c new file mode 100755 index 0000000000000000000000000000000000000000..729f42c50c81432f525a5909c467571757b78ed6 --- /dev/null +++ b/python_part/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_part/python/Objects/dict-common.h b/python_part/python/Objects/dict-common.h new file mode 100755 index 0000000000000000000000000000000000000000..71d6b0274420b83760b6ea684e57922251381cd6 --- /dev/null +++ b/python_part/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_part/python/Objects/dictnotes.txt b/python_part/python/Objects/dictnotes.txt new file mode 100755 index 0000000000000000000000000000000000000000..f89720c9f604e021549b3b3895f5d52cb426dd88 --- /dev/null +++ b/python_part/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_part/python/Objects/dictobject.c b/python_part/python/Objects/dictobject.c new file mode 100755 index 0000000000000000000000000000000000000000..edc02372a1d9274e0642712a8bec6964ead37a82 --- /dev/null +++ b/python_part/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_part/python/Objects/enumobject.c b/python_part/python/Objects/enumobject.c new file mode 100755 index 0000000000000000000000000000000000000000..478a9dd93a32cacf4c94597bebde8515092385ca --- /dev/null +++ b/python_part/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_part/python/Objects/exceptions.c b/python_part/python/Objects/exceptions.c new file mode 100755 index 0000000000000000000000000000000000000000..d22ed6f039ac200cc80eeb0f71aa8dbff2aceea2 --- /dev/null +++ b/python_part/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_part/python/Objects/fileobject.c b/python_part/python/Objects/fileobject.c new file mode 100755 index 0000000000000000000000000000000000000000..dd42d516898a5903de09a50dd6f5210938456536 --- /dev/null +++ b/python_part/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_part/python/Objects/floatobject.c b/python_part/python/Objects/floatobject.c new file mode 100755 index 0000000000000000000000000000000000000000..609f66f8b32ca93a3ec38bbf4e45b0069a55d5eb --- /dev/null +++ b/python_part/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_part/python/Objects/frameobject.c b/python_part/python/Objects/frameobject.c new file mode 100755 index 0000000000000000000000000000000000000000..a796a59eee9e40afdc6e1fba5d4d07ad0501255e --- /dev/null +++ b/python_part/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_part/python/Objects/funcobject.c b/python_part/python/Objects/funcobject.c new file mode 100755 index 0000000000000000000000000000000000000000..0fc4e127081bf46ddd1cfc02095b9e645342d392 --- /dev/null +++ b/python_part/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_part/python/Objects/genobject.c b/python_part/python/Objects/genobject.c new file mode 100755 index 0000000000000000000000000000000000000000..ce7dd48a17cfb6ae36b36c99726520942b0a0c72 --- /dev/null +++ b/python_part/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_part/python/Objects/interpreteridobject.c b/python_part/python/Objects/interpreteridobject.c new file mode 100755 index 0000000000000000000000000000000000000000..19e86a2e0b0f77aa3b74c059b822fc1be69544a5 --- /dev/null +++ b/python_part/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_part/python/Objects/iterobject.c b/python_part/python/Objects/iterobject.c new file mode 100755 index 0000000000000000000000000000000000000000..da89298edc5cf65ab2a916c1f005bec5d4141236 --- /dev/null +++ b/python_part/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_part/python/Objects/listobject.c b/python_part/python/Objects/listobject.c new file mode 100755 index 0000000000000000000000000000000000000000..30444089ffaf96122b581dff08caf8a25f5d8311 --- /dev/null +++ b/python_part/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_part/python/Objects/listsort.txt b/python_part/python/Objects/listsort.txt new file mode 100755 index 0000000000000000000000000000000000000000..174777a2658dc60eeebec775f5c14fb476378f4c --- /dev/null +++ b/python_part/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_part/python/Objects/lnotab_notes.txt b/python_part/python/Objects/lnotab_notes.txt new file mode 100755 index 0000000000000000000000000000000000000000..71a297971828c015fbbebe09490c4a3d6ced1b7e --- /dev/null +++ b/python_part/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_part/python/Objects/longobject.c b/python_part/python/Objects/longobject.c new file mode 100755 index 0000000000000000000000000000000000000000..67dce97471522c575b72eb2140ad5bd59a6f327c --- /dev/null +++ b/python_part/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_part/python/Objects/memoryobject.c b/python_part/python/Objects/memoryobject.c new file mode 100755 index 0000000000000000000000000000000000000000..0bbcbb2e7eefa7db595e7a418f3410ed2c3f8c1a --- /dev/null +++ b/python_part/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_part/python/Objects/methodobject.c b/python_part/python/Objects/methodobject.c new file mode 100755 index 0000000000000000000000000000000000000000..3604a55e5a1dc9458346a619f3811737aa698c31 --- /dev/null +++ b/python_part/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_part/python/Objects/moduleobject.c b/python_part/python/Objects/moduleobject.c new file mode 100755 index 0000000000000000000000000000000000000000..85134c7a11c6bbb18d9759039cc8b0f19c6af7f6 --- /dev/null +++ b/python_part/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_part/python/Objects/namespaceobject.c b/python_part/python/Objects/namespaceobject.c new file mode 100755 index 0000000000000000000000000000000000000000..ddad39a910762bce10865f2358e8437cad64c51a --- /dev/null +++ b/python_part/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_part/python/Objects/object.c b/python_part/python/Objects/object.c new file mode 100755 index 0000000000000000000000000000000000000000..74b1b15d30bbf57254907d064807e79d2ed103f8 --- /dev/null +++ b/python_part/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_part/python/Objects/obmalloc.c b/python_part/python/Objects/obmalloc.c new file mode 100755 index 0000000000000000000000000000000000000000..c483ff3e3b7018ef89222a757f5a5211fdc81602 --- /dev/null +++ b/python_part/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_part/python/Objects/odictobject.c b/python_part/python/Objects/odictobject.c new file mode 100755 index 0000000000000000000000000000000000000000..6076b03455f62b6f55e4589e1a631d922bd0852f --- /dev/null +++ b/python_part/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_part/python/Objects/picklebufobject.c b/python_part/python/Objects/picklebufobject.c new file mode 100755 index 0000000000000000000000000000000000000000..a135e5575e28c52f64831597bc67622e44155ee1 --- /dev/null +++ b/python_part/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_part/python/Objects/rangeobject.c b/python_part/python/Objects/rangeobject.c new file mode 100755 index 0000000000000000000000000000000000000000..239ace6f4235ede252a51664f2d2eb89197ba3ad --- /dev/null +++ b/python_part/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_part/python/Objects/setobject.c b/python_part/python/Objects/setobject.c new file mode 100755 index 0000000000000000000000000000000000000000..f8ae0c05e273cbd2affb0dd9c6086ecb0085c62f --- /dev/null +++ b/python_part/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_part/python/Objects/sliceobject.c b/python_part/python/Objects/sliceobject.c new file mode 100755 index 0000000000000000000000000000000000000000..7c10eb6f638d3a268dc47a04819e2e414b2e4c7d --- /dev/null +++ b/python_part/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_part/python/Objects/stringlib/README.txt b/python_part/python/Objects/stringlib/README.txt new file mode 100755 index 0000000000000000000000000000000000000000..8ff6ad8c4fa0f3eff0058ace4982ed36a3fd3eb2 --- /dev/null +++ b/python_part/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_part/python/Objects/stringlib/asciilib.h b/python_part/python/Objects/stringlib/asciilib.h new file mode 100755 index 0000000000000000000000000000000000000000..8f83614488e844c0d830b739456fe9870fb730d8 --- /dev/null +++ b/python_part/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_part/python/Objects/stringlib/clinic/transmogrify.h.h b/python_part/python/Objects/stringlib/clinic/transmogrify.h.h new file mode 100755 index 0000000000000000000000000000000000000000..8a3a060f12bc9eeafaeb778e1386f104f2c75bb4 --- /dev/null +++ b/python_part/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_part/python/Objects/stringlib/codecs.h b/python_part/python/Objects/stringlib/codecs.h new file mode 100755 index 0000000000000000000000000000000000000000..269a5581f70055261bbdf753a85a33fa4a9e85c4 --- /dev/null +++ b/python_part/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_part/python/Objects/stringlib/count.h b/python_part/python/Objects/stringlib/count.h new file mode 100755 index 0000000000000000000000000000000000000000..f48500bf561f2c23944b9a6158da8d89d3ce1c65 --- /dev/null +++ b/python_part/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_part/python/Objects/stringlib/ctype.h b/python_part/python/Objects/stringlib/ctype.h new file mode 100755 index 0000000000000000000000000000000000000000..843cfa22a84546d409b9d84e2ba69d3a6527a506 --- /dev/null +++ b/python_part/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_part/python/Objects/stringlib/eq.h b/python_part/python/Objects/stringlib/eq.h new file mode 100755 index 0000000000000000000000000000000000000000..ff22f913712e8dfa88a90ad4f7b02e1b3be2975a --- /dev/null +++ b/python_part/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_part/python/Objects/stringlib/fastsearch.h b/python_part/python/Objects/stringlib/fastsearch.h new file mode 100755 index 0000000000000000000000000000000000000000..56a4467d353813e5db41c8c959e8d1639f9335d9 --- /dev/null +++ b/python_part/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_part/python/Objects/stringlib/find.h b/python_part/python/Objects/stringlib/find.h new file mode 100755 index 0000000000000000000000000000000000000000..509b9297396be86552ae9d8d2f6fb371290fe4e5 --- /dev/null +++ b/python_part/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_part/python/Objects/stringlib/find_max_char.h b/python_part/python/Objects/stringlib/find_max_char.h new file mode 100755 index 0000000000000000000000000000000000000000..f4e0a7761d31198bf426dc8b7cbcb70b940ffc0b --- /dev/null +++ b/python_part/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_part/python/Objects/stringlib/join.h b/python_part/python/Objects/stringlib/join.h new file mode 100755 index 0000000000000000000000000000000000000000..6f314e1524eb5403d719fc658a06c9c8d4d3ce2a --- /dev/null +++ b/python_part/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_part/python/Objects/stringlib/localeutil.h b/python_part/python/Objects/stringlib/localeutil.h new file mode 100755 index 0000000000000000000000000000000000000000..bd16e0a172802f04936641465e56f969b5c70013 --- /dev/null +++ b/python_part/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_part/python/Objects/stringlib/partition.h b/python_part/python/Objects/stringlib/partition.h new file mode 100755 index 0000000000000000000000000000000000000000..ed32a6f2b382ec14bb4b46f03037001fe6ed2fec --- /dev/null +++ b/python_part/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_part/python/Objects/stringlib/replace.h b/python_part/python/Objects/stringlib/replace.h new file mode 100755 index 0000000000000000000000000000000000000000..ef318ed6dd5736bc574361b2e975ae642aa159ba --- /dev/null +++ b/python_part/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_part/python/Objects/stringlib/split.h b/python_part/python/Objects/stringlib/split.h new file mode 100755 index 0000000000000000000000000000000000000000..31f77a77243ea94fe83664205fc101593958b8b7 --- /dev/null +++ b/python_part/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_part/python/Objects/stringlib/stringdefs.h b/python_part/python/Objects/stringlib/stringdefs.h new file mode 100755 index 0000000000000000000000000000000000000000..ce27f3e4081f9caf8d8727c5696f29730c023b68 --- /dev/null +++ b/python_part/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_part/python/Objects/stringlib/transmogrify.h b/python_part/python/Objects/stringlib/transmogrify.h new file mode 100755 index 0000000000000000000000000000000000000000..9506019d5af2b8766b3f0cb052f7526651769319 --- /dev/null +++ b/python_part/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_part/python/Objects/stringlib/ucs1lib.h b/python_part/python/Objects/stringlib/ucs1lib.h new file mode 100755 index 0000000000000000000000000000000000000000..ce1eb57f0d7da90bba0cf14217f69693bcec4517 --- /dev/null +++ b/python_part/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_part/python/Objects/stringlib/ucs2lib.h b/python_part/python/Objects/stringlib/ucs2lib.h new file mode 100755 index 0000000000000000000000000000000000000000..f900cb65f8cede16d703d52530239db0b88cc14c --- /dev/null +++ b/python_part/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_part/python/Objects/stringlib/ucs4lib.h b/python_part/python/Objects/stringlib/ucs4lib.h new file mode 100755 index 0000000000000000000000000000000000000000..86a480f1e3a7eda9a5251cbe26ccc1b28ae7e124 --- /dev/null +++ b/python_part/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_part/python/Objects/stringlib/undef.h b/python_part/python/Objects/stringlib/undef.h new file mode 100755 index 0000000000000000000000000000000000000000..f9d3f1d3328d57b93af67e194933f25edf1833ad --- /dev/null +++ b/python_part/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_part/python/Objects/stringlib/unicode_format.h b/python_part/python/Objects/stringlib/unicode_format.h new file mode 100755 index 0000000000000000000000000000000000000000..ddf1e26448693a9c12dcd23e85f62ab68c91545a --- /dev/null +++ b/python_part/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_part/python/Objects/stringlib/unicodedefs.h b/python_part/python/Objects/stringlib/unicodedefs.h new file mode 100755 index 0000000000000000000000000000000000000000..3db5629e11f126066206dbfa83070383368c9dff --- /dev/null +++ b/python_part/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_part/python/Objects/structseq.c b/python_part/python/Objects/structseq.c new file mode 100755 index 0000000000000000000000000000000000000000..c158afccb97fdde8d562226e178e5e88e2754437 --- /dev/null +++ b/python_part/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_part/python/Objects/tupleobject.c b/python_part/python/Objects/tupleobject.c new file mode 100755 index 0000000000000000000000000000000000000000..bd580946b7eb9992ecb568a3034d057552c57c72 --- /dev/null +++ b/python_part/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_part/python/Objects/typeobject.c b/python_part/python/Objects/typeobject.c new file mode 100755 index 0000000000000000000000000000000000000000..6fbeac2a9392670744121c5764ba1771f43779c8 --- /dev/null +++ b/python_part/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_part/python/Objects/typeslots.inc b/python_part/python/Objects/typeslots.inc new file mode 100755 index 0000000000000000000000000000000000000000..dc750cc0c41975963fb3af1a94286c6a2e356e5f --- /dev/null +++ b/python_part/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_part/python/Objects/typeslots.py b/python_part/python/Objects/typeslots.py new file mode 100755 index 0000000000000000000000000000000000000000..9b6d4adbc7533b5abc00b0e41e0b78872d0560c3 --- /dev/null +++ b/python_part/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_part/python/Objects/unicodectype.c b/python_part/python/Objects/unicodectype.c new file mode 100755 index 0000000000000000000000000000000000000000..d8c95c8b44cea71ec201812af4a0c4884b933555 --- /dev/null +++ b/python_part/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_part/python/Objects/unicodeobject.c b/python_part/python/Objects/unicodeobject.c new file mode 100755 index 0000000000000000000000000000000000000000..4554f612c0416f261c20344075c18be21e683bcf --- /dev/null +++ b/python_part/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_part/python/Objects/unicodetype_db.h b/python_part/python/Objects/unicodetype_db.h new file mode 100755 index 0000000000000000000000000000000000000000..693e0b3ef0b499f7972b30b2c3243bf80af249b1 --- /dev/null +++ b/python_part/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_part/python/Objects/weakrefobject.c b/python_part/python/Objects/weakrefobject.c new file mode 100755 index 0000000000000000000000000000000000000000..58fe09fa3b51b025a309c09ddeeb45b854292ab6 --- /dev/null +++ b/python_part/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_part/python/Parser/Python.asdl b/python_part/python/Parser/Python.asdl new file mode 100755 index 0000000000000000000000000000000000000000..126d478975bbbb449e600fcecff5072a7239bd94 --- /dev/null +++ b/python_part/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_part/python/Parser/acceler.c b/python_part/python/Parser/acceler.c new file mode 100755 index 0000000000000000000000000000000000000000..e515833e1dda1d4924a3a94892d90a6c6cb6a6b4 --- /dev/null +++ b/python_part/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_part/python/Parser/asdl.py b/python_part/python/Parser/asdl.py new file mode 100755 index 0000000000000000000000000000000000000000..62f5c19c99fd711455db750df3b07978dfa0b3a2 --- /dev/null +++ b/python_part/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_part/python/Parser/asdl_c.py b/python_part/python/Parser/asdl_c.py new file mode 100755 index 0000000000000000000000000000000000000000..a708b66dbe917989d0bb043a9e074bb967d29cd4 --- /dev/null +++ b/python_part/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_part/python/Parser/grammar1.c b/python_part/python/Parser/grammar1.c new file mode 100755 index 0000000000000000000000000000000000000000..e0b8fbb8b82886bea64db250d46ad9e9d84e3e33 --- /dev/null +++ b/python_part/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_part/python/Parser/listnode.c b/python_part/python/Parser/listnode.c new file mode 100755 index 0000000000000000000000000000000000000000..8f1a1163b63d5c137b0d0e3b01ac655339a8c73b --- /dev/null +++ b/python_part/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_part/python/Parser/myreadline.c b/python_part/python/Parser/myreadline.c new file mode 100755 index 0000000000000000000000000000000000000000..e8e57738f3377fbbc77c5587a96c279551125b36 --- /dev/null +++ b/python_part/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_part/python/Parser/node.c b/python_part/python/Parser/node.c new file mode 100755 index 0000000000000000000000000000000000000000..f1b70e0f6815be206c96b18b56baa6b6a0bf4a9f --- /dev/null +++ b/python_part/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_part/python/Parser/parser.c b/python_part/python/Parser/parser.c new file mode 100755 index 0000000000000000000000000000000000000000..227b9184f471d22af132480ff26d18ef0a06e24c --- /dev/null +++ b/python_part/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_part/python/Parser/parser.h b/python_part/python/Parser/parser.h new file mode 100755 index 0000000000000000000000000000000000000000..b16075e7f29f29922949aec9e4b2df9960060777 --- /dev/null +++ b/python_part/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_part/python/Parser/parsetok.c b/python_part/python/Parser/parsetok.c new file mode 100755 index 0000000000000000000000000000000000000000..2bb733d0dcd66bc66eab1569c1335ec3511c4a35 --- /dev/null +++ b/python_part/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_part/python/Parser/pgen/__init__.py b/python_part/python/Parser/pgen/__init__.py new file mode 100755 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/python_part/python/Parser/pgen/__main__.py b/python_part/python/Parser/pgen/__main__.py new file mode 100755 index 0000000000000000000000000000000000000000..eea52618422e41b752b10045d2b8fecedb8a2596 --- /dev/null +++ b/python_part/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_part/python/Parser/pgen/grammar.py b/python_part/python/Parser/pgen/grammar.py new file mode 100755 index 0000000000000000000000000000000000000000..5cd652426b475573a4fb22588d0742be86193fda --- /dev/null +++ b/python_part/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_part/python/Parser/pgen/keywordgen.py b/python_part/python/Parser/pgen/keywordgen.py new file mode 100755 index 0000000000000000000000000000000000000000..eeb3ef739fadefcbb0a897020deaba8956f3310c --- /dev/null +++ b/python_part/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_part/python/Parser/pgen/pgen.py b/python_part/python/Parser/pgen/pgen.py new file mode 100755 index 0000000000000000000000000000000000000000..d52d58f64e41cc6c9c14aac87130cea430f44c43 --- /dev/null +++ b/python_part/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_part/python/Parser/pgen/token.py b/python_part/python/Parser/pgen/token.py new file mode 100755 index 0000000000000000000000000000000000000000..008e241e175e7f9da94899dcf9b4994db85c8c53 --- /dev/null +++ b/python_part/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_part/python/Parser/token.c b/python_part/python/Parser/token.c new file mode 100755 index 0000000000000000000000000000000000000000..a489668900901d70420da1f2886b29df71d62d28 --- /dev/null +++ b/python_part/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_part/python/Parser/tokenizer.c b/python_part/python/Parser/tokenizer.c new file mode 100755 index 0000000000000000000000000000000000000000..aecbcebb917e8370327940e7a98b40684ad5d303 --- /dev/null +++ b/python_part/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_part/python/Parser/tokenizer.h b/python_part/python/Parser/tokenizer.h new file mode 100755 index 0000000000000000000000000000000000000000..92669bfd8a1607fbe450ee9f904f949dac9075f4 --- /dev/null +++ b/python_part/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_part/python/Programs/README b/python_part/python/Programs/README new file mode 100755 index 0000000000000000000000000000000000000000..c24578bc08d25c11337ab6ec1b99978f1fd57895 --- /dev/null +++ b/python_part/python/Programs/README @@ -0,0 +1 @@ +Source files for binary executables (as opposed to shared modules) diff --git a/python_part/python/Programs/_freeze_importlib.c b/python_part/python/Programs/_freeze_importlib.c new file mode 100755 index 0000000000000000000000000000000000000000..2e4ccbb154a414d3bbe4696ed626c049458d7ab0 --- /dev/null +++ b/python_part/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_part/python/Programs/_testembed b/python_part/python/Programs/_testembed new file mode 100755 index 0000000000000000000000000000000000000000..57b87fc9d8f57d9cbaf1faed83b1d2e6976c0544 Binary files /dev/null and b/python_part/python/Programs/_testembed differ diff --git a/python_part/python/Programs/_testembed.c b/python_part/python/Programs/_testembed.c new file mode 100755 index 0000000000000000000000000000000000000000..460d70ccadefd5ea78aba3b42f27017effbe8116 --- /dev/null +++ b/python_part/python/Programs/_testembed.c @@ -0,0 +1,1682 @@ +#ifndef Py_BUILD_CORE_MODULE +# define Py_BUILD_CORE_MODULE +#endif + +/* Always enable assertion (even in release mode) */ +#undef NDEBUG + +#include +#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_part/python/Programs/python.c b/python_part/python/Programs/python.c new file mode 100755 index 0000000000000000000000000000000000000000..1cc3c42cfcbf9323c93134c039666be895198bbd --- /dev/null +++ b/python_part/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_part/python/Python/Python-ast.c b/python_part/python/Python/Python-ast.c new file mode 100755 index 0000000000000000000000000000000000000000..bcf9456942c6fc44b51b28d1ff1bb43618936bad --- /dev/null +++ b/python_part/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_part/python/Python/README b/python_part/python/Python/README new file mode 100755 index 0000000000000000000000000000000000000000..153b628bd5b42d6c85be1bde85c35cdf53c4b6fb --- /dev/null +++ b/python_part/python/Python/README @@ -0,0 +1 @@ +Miscellaneous source files for the main Python shared library diff --git a/python_part/python/Python/_warnings.c b/python_part/python/Python/_warnings.c new file mode 100755 index 0000000000000000000000000000000000000000..52a13dfc62ccca8c0b19dc27bce7ff53714eb55d --- /dev/null +++ b/python_part/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_part/python/Python/asdl.c b/python_part/python/Python/asdl.c new file mode 100755 index 0000000000000000000000000000000000000000..c21107811813af96ca21a15ae508b0ae39bf9a6e --- /dev/null +++ b/python_part/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_part/python/Python/ast.c b/python_part/python/Python/ast.c new file mode 100755 index 0000000000000000000000000000000000000000..7c1d24dea7184fac9619e3f41c1adf171bbdcc66 --- /dev/null +++ b/python_part/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_part/python/Python/ast_opt.c b/python_part/python/Python/ast_opt.c new file mode 100755 index 0000000000000000000000000000000000000000..f2a2c259149932e8a4c0377c4bb5d8a7a70f51f1 --- /dev/null +++ b/python_part/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_part/python/Python/ast_unparse.c b/python_part/python/Python/ast_unparse.c new file mode 100755 index 0000000000000000000000000000000000000000..af9604eb45b18366e30d6bc1630d9d53e51d5e56 --- /dev/null +++ b/python_part/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_part/python/Python/bltinmodule.c b/python_part/python/Python/bltinmodule.c new file mode 100755 index 0000000000000000000000000000000000000000..3767f552bb17aa8410f7d34259d473c52c8bbd60 --- /dev/null +++ b/python_part/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_part/python/Python/bootstrap_hash.c b/python_part/python/Python/bootstrap_hash.c new file mode 100755 index 0000000000000000000000000000000000000000..eb2b6d08d8e1429a514500ffc6138c88e3ef7b1a --- /dev/null +++ b/python_part/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_part/python/Python/ceval.c b/python_part/python/Python/ceval.c new file mode 100755 index 0000000000000000000000000000000000000000..1873e37cf608e88e93b2351b37aa906fc71e75df --- /dev/null +++ b/python_part/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_part/python/Python/ceval_gil.h b/python_part/python/Python/ceval_gil.h new file mode 100755 index 0000000000000000000000000000000000000000..96794dfe4130a3ec324cc714b89c744e3ad10556 --- /dev/null +++ b/python_part/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_part/python/Python/clinic/_warnings.c.h b/python_part/python/Python/clinic/_warnings.c.h new file mode 100755 index 0000000000000000000000000000000000000000..67ab0e3d9de5251629972d1ed8fe7541be19712b --- /dev/null +++ b/python_part/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_part/python/Python/clinic/bltinmodule.c.h b/python_part/python/Python/clinic/bltinmodule.c.h new file mode 100755 index 0000000000000000000000000000000000000000..d15af1f7f377c6f29cc17de7cf462cf13bceea19 --- /dev/null +++ b/python_part/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_part/python/Python/clinic/context.c.h b/python_part/python/Python/clinic/context.c.h new file mode 100755 index 0000000000000000000000000000000000000000..2ac8bf7c0b8ca01db1f09f78b3619cf7711d6a8e --- /dev/null +++ b/python_part/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_part/python/Python/clinic/import.c.h b/python_part/python/Python/clinic/import.c.h new file mode 100755 index 0000000000000000000000000000000000000000..782fdc2d3426daa9791f9c20ccf704faca8e3c68 --- /dev/null +++ b/python_part/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_part/python/Python/clinic/marshal.c.h b/python_part/python/Python/clinic/marshal.c.h new file mode 100755 index 0000000000000000000000000000000000000000..05d4830c4ab313c73636d0438cab50f63e0d5274 --- /dev/null +++ b/python_part/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_part/python/Python/clinic/sysmodule.c.h b/python_part/python/Python/clinic/sysmodule.c.h new file mode 100755 index 0000000000000000000000000000000000000000..d2d1503926205d0be172849ad176793764ad0516 --- /dev/null +++ b/python_part/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_part/python/Python/clinic/traceback.c.h b/python_part/python/Python/clinic/traceback.c.h new file mode 100755 index 0000000000000000000000000000000000000000..04daf2a3766988d256b8209ca266ff6af8c7dc6f --- /dev/null +++ b/python_part/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_part/python/Python/codecs.c b/python_part/python/Python/codecs.c new file mode 100755 index 0000000000000000000000000000000000000000..4bd28ec9c761cae99ddef8047ac759ea38cf7828 --- /dev/null +++ b/python_part/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_part/python/Python/compile.c b/python_part/python/Python/compile.c new file mode 100755 index 0000000000000000000000000000000000000000..3259e8a47f2d8d1be87ad9c345e7953e9aeddd06 --- /dev/null +++ b/python_part/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_part/python/Python/condvar.h b/python_part/python/Python/condvar.h new file mode 100755 index 0000000000000000000000000000000000000000..8cba19b84612dc77981a788d42de77052f52e418 --- /dev/null +++ b/python_part/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_part/python/Python/context.c b/python_part/python/Python/context.c new file mode 100755 index 0000000000000000000000000000000000000000..5c30e47f35dd7896f099711cffac547045237800 --- /dev/null +++ b/python_part/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_part/python/Python/dtoa.c b/python_part/python/Python/dtoa.c new file mode 100755 index 0000000000000000000000000000000000000000..b7bb7acfb6c215a46840d3c5696968c261f0225a --- /dev/null +++ b/python_part/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_part/python/Python/dup2.c b/python_part/python/Python/dup2.c new file mode 100755 index 0000000000000000000000000000000000000000..7c6bbfce11dbf80dae7fe4c79d4c52839a0c68ad --- /dev/null +++ b/python_part/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_part/python/Python/dynamic_annotations.c b/python_part/python/Python/dynamic_annotations.c new file mode 100755 index 0000000000000000000000000000000000000000..7febaa09df195043d473c2171610d3219d7936d5 --- /dev/null +++ b/python_part/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_part/python/Python/dynload_aix.c b/python_part/python/Python/dynload_aix.c new file mode 100755 index 0000000000000000000000000000000000000000..25fe19e601acbebc632fd7a23c8ff86ed51bb204 --- /dev/null +++ b/python_part/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_part/python/Python/dynload_dl.c b/python_part/python/Python/dynload_dl.c new file mode 100755 index 0000000000000000000000000000000000000000..2bec645fbd7aff02d08363cc2c40c057055b86fb --- /dev/null +++ b/python_part/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_part/python/Python/dynload_hpux.c b/python_part/python/Python/dynload_hpux.c new file mode 100755 index 0000000000000000000000000000000000000000..9fa003c944a7b45a7fe729f352bc69bfedd6b2fc --- /dev/null +++ b/python_part/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_part/python/Python/dynload_shlib.c b/python_part/python/Python/dynload_shlib.c new file mode 100755 index 0000000000000000000000000000000000000000..dd7e7d7600297f3c07d97f9bdd54d41db5047452 --- /dev/null +++ b/python_part/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_part/python/Python/dynload_stub.c b/python_part/python/Python/dynload_stub.c new file mode 100755 index 0000000000000000000000000000000000000000..495364c8445fc8b458f283c69af79ec0967adf8d --- /dev/null +++ b/python_part/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_part/python/Python/dynload_win.c b/python_part/python/Python/dynload_win.c new file mode 100755 index 0000000000000000000000000000000000000000..4896c6dc8c25dd0a6c826d0e3853d366a2aed541 --- /dev/null +++ b/python_part/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_part/python/Python/errors.c b/python_part/python/Python/errors.c new file mode 100755 index 0000000000000000000000000000000000000000..1360c0d91a33fa3ccced80aa0fb09df9da34fd6d --- /dev/null +++ b/python_part/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_part/python/Python/fileutils.c b/python_part/python/Python/fileutils.c new file mode 100755 index 0000000000000000000000000000000000000000..3e1311c97868674d9431b0d19870048035be80b1 --- /dev/null +++ b/python_part/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_part/python/Python/formatter_unicode.c b/python_part/python/Python/formatter_unicode.c new file mode 100755 index 0000000000000000000000000000000000000000..7c4ecf0b3e2cb7770248308823a7a5bd803a7093 --- /dev/null +++ b/python_part/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_part/python/Python/frozen.c b/python_part/python/Python/frozen.c new file mode 100755 index 0000000000000000000000000000000000000000..228a11019cfa6a8aa1237afe60a5d24c9405450e --- /dev/null +++ b/python_part/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_part/python/Python/frozenmain.c b/python_part/python/Python/frozenmain.c new file mode 100755 index 0000000000000000000000000000000000000000..7f9cc193173605f5cfc1d0e643d4e1a2c719984b --- /dev/null +++ b/python_part/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_part/python/Python/future.c b/python_part/python/Python/future.c new file mode 100755 index 0000000000000000000000000000000000000000..1663a38a6fdb3a4c7f32aff732f0d259d7e98d3b --- /dev/null +++ b/python_part/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_part/python/Python/getargs.c b/python_part/python/Python/getargs.c new file mode 100755 index 0000000000000000000000000000000000000000..c1b7b1a275b00900c6a7ab2a7992590d023c8457 --- /dev/null +++ b/python_part/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_part/python/Python/getcompiler.c b/python_part/python/Python/getcompiler.c new file mode 100755 index 0000000000000000000000000000000000000000..59c0dbf92aebf42fabf41661b8262aa89a15b60b --- /dev/null +++ b/python_part/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_part/python/Python/getcopyright.c b/python_part/python/Python/getcopyright.c new file mode 100755 index 0000000000000000000000000000000000000000..7fdeb314d5261b97ceea5c876b82a58bc2a238d5 --- /dev/null +++ b/python_part/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_part/python/Python/getopt.c b/python_part/python/Python/getopt.c new file mode 100755 index 0000000000000000000000000000000000000000..249ad1e8736075eedcf3331a4eb06493db75fd00 --- /dev/null +++ b/python_part/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_part/python/Python/getplatform.c b/python_part/python/Python/getplatform.c new file mode 100755 index 0000000000000000000000000000000000000000..81a0f7ac5378bd55e02ab93148293266d8491921 --- /dev/null +++ b/python_part/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_part/python/Python/getversion.c b/python_part/python/Python/getversion.c new file mode 100755 index 0000000000000000000000000000000000000000..c32b6f9d60d4b751d30d0539f103ee7c52e6a633 --- /dev/null +++ b/python_part/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_part/python/Python/graminit.c b/python_part/python/Python/graminit.c new file mode 100755 index 0000000000000000000000000000000000000000..7c40ce933c1d61672b0f760f265e6d843219b909 --- /dev/null +++ b/python_part/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_part/python/Python/hamt.c b/python_part/python/Python/hamt.c new file mode 100755 index 0000000000000000000000000000000000000000..5efc8d7fabe8e33322b7179892967b1b8190a11b --- /dev/null +++ b/python_part/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_part/python/Python/import.c b/python_part/python/Python/import.c new file mode 100755 index 0000000000000000000000000000000000000000..35c5561221da24c9d676c94ba6f7595a39b50a35 --- /dev/null +++ b/python_part/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_part/python/Python/importdl.c b/python_part/python/Python/importdl.c new file mode 100755 index 0000000000000000000000000000000000000000..b07187466106bfeae34e37fa36f804d881710158 --- /dev/null +++ b/python_part/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_part/python/Python/importdl.h b/python_part/python/Python/importdl.h new file mode 100755 index 0000000000000000000000000000000000000000..9847652b1f1b31ceec1e9390fbbbce1702348a6e --- /dev/null +++ b/python_part/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_part/python/Python/importlib.h b/python_part/python/Python/importlib.h new file mode 100755 index 0000000000000000000000000000000000000000..67195747d8d90c7bd58313aa6d6f9446b417fee3 --- /dev/null +++ b/python_part/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_part/python/Python/importlib_external.h b/python_part/python/Python/importlib_external.h new file mode 100755 index 0000000000000000000000000000000000000000..3327c3328236a5be2f1be8c6d86dab4810a21b57 --- /dev/null +++ b/python_part/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_part/python/Python/importlib_zipimport.h b/python_part/python/Python/importlib_zipimport.h new file mode 100755 index 0000000000000000000000000000000000000000..f013b41457fd4343be4e489572f9b360ef366889 --- /dev/null +++ b/python_part/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_part/python/Python/initconfig.c b/python_part/python/Python/initconfig.c new file mode 100755 index 0000000000000000000000000000000000000000..69711d8eab3fc0ba0bd75333bb777d1f2b249763 --- /dev/null +++ b/python_part/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_part/python/Python/makeopcodetargets.py b/python_part/python/Python/makeopcodetargets.py new file mode 100755 index 0000000000000000000000000000000000000000..023c9e6c9f1adc1ce9d1e4223f77f90cfde6729b --- /dev/null +++ b/python_part/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_part/python/Python/marshal.c b/python_part/python/Python/marshal.c new file mode 100755 index 0000000000000000000000000000000000000000..a9ba7a436fd19d279f1e70483e5c41af0da76097 --- /dev/null +++ b/python_part/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_part/python/Python/modsupport.c b/python_part/python/Python/modsupport.c new file mode 100755 index 0000000000000000000000000000000000000000..506281191c522c047bee2aa5eca6021a580a9f79 --- /dev/null +++ b/python_part/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_part/python/Python/mysnprintf.c b/python_part/python/Python/mysnprintf.c new file mode 100755 index 0000000000000000000000000000000000000000..a08e249b42b1ef25a268c6f6c500d7aacc6227ce --- /dev/null +++ b/python_part/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_part/python/Python/mystrtoul.c b/python_part/python/Python/mystrtoul.c new file mode 100755 index 0000000000000000000000000000000000000000..7ab5814272d55a45792d865821c12e423e6167f6 --- /dev/null +++ b/python_part/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_part/python/Python/opcode_targets.h b/python_part/python/Python/opcode_targets.h new file mode 100755 index 0000000000000000000000000000000000000000..e82959be086455f7487f092820f1de0a1dbf777b --- /dev/null +++ b/python_part/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_part/python/Python/pathconfig.c b/python_part/python/Python/pathconfig.c new file mode 100755 index 0000000000000000000000000000000000000000..60c104492d6468da7721c0487bc6b48e49235174 --- /dev/null +++ b/python_part/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_part/python/Python/peephole.c b/python_part/python/Python/peephole.c new file mode 100755 index 0000000000000000000000000000000000000000..d859648411fa3f6452caf400a39fb68f56625b0a --- /dev/null +++ b/python_part/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_part/python/Python/preconfig.c b/python_part/python/Python/preconfig.c new file mode 100755 index 0000000000000000000000000000000000000000..89a6227fa67218dc428eeb53815eb1fb82e6a3b8 --- /dev/null +++ b/python_part/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_part/python/Python/pyarena.c b/python_part/python/Python/pyarena.c new file mode 100755 index 0000000000000000000000000000000000000000..aefb787e554f9661f2df538ac70070ceeaad55c8 --- /dev/null +++ b/python_part/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_part/python/Python/pyctype.c b/python_part/python/Python/pyctype.c new file mode 100755 index 0000000000000000000000000000000000000000..da117d58fd0684cd971b298406b67923933a06f1 --- /dev/null +++ b/python_part/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_part/python/Python/pyfpe.c b/python_part/python/Python/pyfpe.c new file mode 100755 index 0000000000000000000000000000000000000000..31ef5d73b70ac70a9f6e449a437e68b698e09590 --- /dev/null +++ b/python_part/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_part/python/Python/pyhash.c b/python_part/python/Python/pyhash.c new file mode 100755 index 0000000000000000000000000000000000000000..c0355ae686afd2272b2ad1639b2021544b8b4bae --- /dev/null +++ b/python_part/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_part/python/Python/pylifecycle.c b/python_part/python/Python/pylifecycle.c new file mode 100755 index 0000000000000000000000000000000000000000..8732d814f819aebde07388575be65c97cc604810 --- /dev/null +++ b/python_part/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_part/python/Python/pymath.c b/python_part/python/Python/pymath.c new file mode 100755 index 0000000000000000000000000000000000000000..24b804223eef19a9e551d6916ea1230f7bfd7644 --- /dev/null +++ b/python_part/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_part/python/Python/pystate.c b/python_part/python/Python/pystate.c new file mode 100755 index 0000000000000000000000000000000000000000..56c184e43ae0ef9b2a08cec22909e55714a6917e --- /dev/null +++ b/python_part/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_part/python/Python/pystrcmp.c b/python_part/python/Python/pystrcmp.c new file mode 100755 index 0000000000000000000000000000000000000000..9224ce4c70605526dca14bc2bbe26b4280e6b543 --- /dev/null +++ b/python_part/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_part/python/Python/pystrhex.c b/python_part/python/Python/pystrhex.c new file mode 100755 index 0000000000000000000000000000000000000000..9d34f71a2e9cf3e33f4fdd8d7185a1a7d7746068 --- /dev/null +++ b/python_part/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_part/python/Python/pystrtod.c b/python_part/python/Python/pystrtod.c new file mode 100755 index 0000000000000000000000000000000000000000..4aa99d546caf9e7286c5e59bebc2e5e5cf5015b8 --- /dev/null +++ b/python_part/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_part/python/Python/pythonrun.c b/python_part/python/Python/pythonrun.c new file mode 100755 index 0000000000000000000000000000000000000000..c55e7674a665c1aaf58dd4188aec766db19cdfae --- /dev/null +++ b/python_part/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_part/python/Python/pytime.c b/python_part/python/Python/pytime.c new file mode 100755 index 0000000000000000000000000000000000000000..109d52692ce4860e16b38638872227eba3c1d007 --- /dev/null +++ b/python_part/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_part/python/Python/strdup.c b/python_part/python/Python/strdup.c new file mode 100755 index 0000000000000000000000000000000000000000..af39a1ea2d11e8c98146ad4b5d43960dfb98899e --- /dev/null +++ b/python_part/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_part/python/Python/structmember.c b/python_part/python/Python/structmember.c new file mode 100755 index 0000000000000000000000000000000000000000..e653d0277c1a106398546b832677bb865faea9ee --- /dev/null +++ b/python_part/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_part/python/Python/symtable.c b/python_part/python/Python/symtable.c new file mode 100755 index 0000000000000000000000000000000000000000..30482d99b3ca927c2034c0e3e84fb202179b2756 --- /dev/null +++ b/python_part/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_part/python/Python/sysmodule.c b/python_part/python/Python/sysmodule.c new file mode 100755 index 0000000000000000000000000000000000000000..b544f2b793ec99860ed2c5d61a8ae6d9e6ed80f1 --- /dev/null +++ b/python_part/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_part/python/Python/thread.c b/python_part/python/Python/thread.c new file mode 100755 index 0000000000000000000000000000000000000000..c36ce6ff9835d869d94c9e8f3c9057d101a4b881 --- /dev/null +++ b/python_part/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_part/python/Python/thread_nt.h b/python_part/python/Python/thread_nt.h new file mode 100755 index 0000000000000000000000000000000000000000..23d585cf9fa6c00f3038ef48a83a5b9fac236440 --- /dev/null +++ b/python_part/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_part/python/Python/thread_pthread.h b/python_part/python/Python/thread_pthread.h new file mode 100755 index 0000000000000000000000000000000000000000..78b99a77206c9485a04fce70ec205df55a76e702 --- /dev/null +++ b/python_part/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_part/python/Python/traceback.c b/python_part/python/Python/traceback.c new file mode 100755 index 0000000000000000000000000000000000000000..0aa51ad37f49e279efa65463b22cd86913f3f786 --- /dev/null +++ b/python_part/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_part/python/Python/wordcode_helpers.h b/python_part/python/Python/wordcode_helpers.h new file mode 100755 index 0000000000000000000000000000000000000000..c8f7a0f41f903506a3e43b3d616d804cece3d355 --- /dev/null +++ b/python_part/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_part/python/include/Python-ast.h b/python_part/python/include/Python-ast.h new file mode 100755 index 0000000000000000000000000000000000000000..5fe4f2b4314c6991a49289f0a8511cad8513746b --- /dev/null +++ b/python_part/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_part/python/include/Python.h b/python_part/python/include/Python.h new file mode 100755 index 0000000000000000000000000000000000000000..d6e5b139ac67964e8457bfd57304157b0eabafb3 --- /dev/null +++ b/python_part/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_part/python/include/abstract.h b/python_part/python/include/abstract.h new file mode 100755 index 0000000000000000000000000000000000000000..777fd7077c2d6520cd97473dbc0874359084824a --- /dev/null +++ b/python_part/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_part/python/include/asdl.h b/python_part/python/include/asdl.h new file mode 100755 index 0000000000000000000000000000000000000000..fc6d22371b63fac2c99840083c4a088ba354eab4 --- /dev/null +++ b/python_part/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_part/python/include/ast.h b/python_part/python/include/ast.h new file mode 100755 index 0000000000000000000000000000000000000000..f1d734852eca79ffb0ebf213751461c8ec54d64d --- /dev/null +++ b/python_part/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_part/python/include/bitset.h b/python_part/python/include/bitset.h new file mode 100755 index 0000000000000000000000000000000000000000..6a2ac9787eaba30743b053e405c90e09a6308516 --- /dev/null +++ b/python_part/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_part/python/include/bltinmodule.h b/python_part/python/include/bltinmodule.h new file mode 100755 index 0000000000000000000000000000000000000000..868c9e6443bfc1d1d48fb0806af1bf21490fc44c --- /dev/null +++ b/python_part/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_part/python/include/boolobject.h b/python_part/python/include/boolobject.h new file mode 100755 index 0000000000000000000000000000000000000000..7cc2f1fe23937acbca1ac7c2f3e4654395214b1b --- /dev/null +++ b/python_part/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_part/python/include/bytearrayobject.h b/python_part/python/include/bytearrayobject.h new file mode 100755 index 0000000000000000000000000000000000000000..a757b880592979fe8f2496f32b95868273a71b1a --- /dev/null +++ b/python_part/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_part/python/include/bytes_methods.h b/python_part/python/include/bytes_methods.h new file mode 100755 index 0000000000000000000000000000000000000000..8434a50a4bba717ee6c3a4428de3be3677e5c928 --- /dev/null +++ b/python_part/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_part/python/include/bytesobject.h b/python_part/python/include/bytesobject.h new file mode 100755 index 0000000000000000000000000000000000000000..3fde4a221fdb18b5e50e5eb3936675f553ed00ea --- /dev/null +++ b/python_part/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_part/python/include/cellobject.h b/python_part/python/include/cellobject.h new file mode 100755 index 0000000000000000000000000000000000000000..2f9b5b75d998aeda50113fe4b62849fdcf4714e6 --- /dev/null +++ b/python_part/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_part/python/include/ceval.h b/python_part/python/include/ceval.h new file mode 100755 index 0000000000000000000000000000000000000000..36fd014a91a7dd26c6d0071fa20db0a4ded241ec --- /dev/null +++ b/python_part/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_part/python/include/classobject.h b/python_part/python/include/classobject.h new file mode 100755 index 0000000000000000000000000000000000000000..c83303c390055380d1777c6233b90f36200c438c --- /dev/null +++ b/python_part/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_part/python/include/code.h b/python_part/python/include/code.h new file mode 100755 index 0000000000000000000000000000000000000000..a1cd58f44a0e892b6ac1b6a9e63e572e75c11765 --- /dev/null +++ b/python_part/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_part/python/include/codecs.h b/python_part/python/include/codecs.h new file mode 100755 index 0000000000000000000000000000000000000000..3ad0f2b5aae79c71c54fabfd51a41aca618f1ac0 --- /dev/null +++ b/python_part/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_part/python/include/compile.h b/python_part/python/include/compile.h new file mode 100755 index 0000000000000000000000000000000000000000..015584d03b0233aba038f8e1e2c0032a53739b57 --- /dev/null +++ b/python_part/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_part/python/include/complexobject.h b/python_part/python/include/complexobject.h new file mode 100755 index 0000000000000000000000000000000000000000..cb8c52c580085444313fc6aee36401be638ffd3e --- /dev/null +++ b/python_part/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_part/python/include/context.h b/python_part/python/include/context.h new file mode 100755 index 0000000000000000000000000000000000000000..9581285247b3976e2973dcae3a6d22c305dc624c --- /dev/null +++ b/python_part/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_part/python/include/cpython/abstract.h b/python_part/python/include/cpython/abstract.h new file mode 100755 index 0000000000000000000000000000000000000000..dbfce2dc9061db3ab5d5b4b1bcae63af4a0c9c39 --- /dev/null +++ b/python_part/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_part/python/include/cpython/dictobject.h b/python_part/python/include/cpython/dictobject.h new file mode 100755 index 0000000000000000000000000000000000000000..64c012a012b793bf5f5954ab67f880ae81cda138 --- /dev/null +++ b/python_part/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_part/python/include/cpython/fileobject.h b/python_part/python/include/cpython/fileobject.h new file mode 100755 index 0000000000000000000000000000000000000000..3005ce1f00f9d5b7644fde56fb064ade7abbff5f --- /dev/null +++ b/python_part/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_part/python/include/cpython/initconfig.h b/python_part/python/include/cpython/initconfig.h new file mode 100755 index 0000000000000000000000000000000000000000..4b5ceafe02dbc22faf65eea69a9cf043f20431be --- /dev/null +++ b/python_part/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_part/python/include/cpython/interpreteridobject.h b/python_part/python/include/cpython/interpreteridobject.h new file mode 100755 index 0000000000000000000000000000000000000000..67ec5873542d84765918ff0f9e76d17d4014d401 --- /dev/null +++ b/python_part/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_part/python/include/cpython/object.h b/python_part/python/include/cpython/object.h new file mode 100755 index 0000000000000000000000000000000000000000..5a0ac4afdae83d91a6211172834f5a0afbc2f832 --- /dev/null +++ b/python_part/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_part/python/include/cpython/objimpl.h b/python_part/python/include/cpython/objimpl.h new file mode 100755 index 0000000000000000000000000000000000000000..f121922bc42ced372845ca462c7ba742d4856710 --- /dev/null +++ b/python_part/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_part/python/include/cpython/pyerrors.h b/python_part/python/include/cpython/pyerrors.h new file mode 100755 index 0000000000000000000000000000000000000000..418f48a7e2baefa734bcf46344df2ff5d4dc895a --- /dev/null +++ b/python_part/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_part/python/include/cpython/pylifecycle.h b/python_part/python/include/cpython/pylifecycle.h new file mode 100755 index 0000000000000000000000000000000000000000..2f3a0dbdfe64c52f3dcc29c04654628baaf0a146 --- /dev/null +++ b/python_part/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_part/python/include/cpython/pymem.h b/python_part/python/include/cpython/pymem.h new file mode 100755 index 0000000000000000000000000000000000000000..79f063b1217534b8f3fc0b494ec55f3736f33f81 --- /dev/null +++ b/python_part/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_part/python/include/cpython/pystate.h b/python_part/python/include/cpython/pystate.h new file mode 100755 index 0000000000000000000000000000000000000000..e22b0539136083eea918f7ea42906c7419aa0863 --- /dev/null +++ b/python_part/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_part/python/include/cpython/sysmodule.h b/python_part/python/include/cpython/sysmodule.h new file mode 100755 index 0000000000000000000000000000000000000000..72d8ffed29fd6f73f8b2c6f157dbbdf86aa36bcb --- /dev/null +++ b/python_part/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_part/python/include/cpython/traceback.h b/python_part/python/include/cpython/traceback.h new file mode 100755 index 0000000000000000000000000000000000000000..746097daaf9400cfb783eba79d73d70d32217c69 --- /dev/null +++ b/python_part/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_part/python/include/cpython/tupleobject.h b/python_part/python/include/cpython/tupleobject.h new file mode 100755 index 0000000000000000000000000000000000000000..1565f2a5c3d986ac041208e57d32e8969e48a583 --- /dev/null +++ b/python_part/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_part/python/include/cpython/unicodeobject.h b/python_part/python/include/cpython/unicodeobject.h new file mode 100755 index 0000000000000000000000000000000000000000..87ff31ddbc101c6de25ce37f169981b27e1cedb4 --- /dev/null +++ b/python_part/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_part/python/include/datetime.h b/python_part/python/include/datetime.h new file mode 100755 index 0000000000000000000000000000000000000000..00507cb85cc04aaf3fdd229547d3d8d8aa4e65de --- /dev/null +++ b/python_part/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_part/python/include/descrobject.h b/python_part/python/include/descrobject.h new file mode 100755 index 0000000000000000000000000000000000000000..ead269d1d2f796b5f4cf9c00284f9da7f5e79964 --- /dev/null +++ b/python_part/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_part/python/include/dictobject.h b/python_part/python/include/dictobject.h new file mode 100755 index 0000000000000000000000000000000000000000..b37573ad48c003d3f700c1073585244c672bc563 --- /dev/null +++ b/python_part/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_part/python/include/dtoa.h b/python_part/python/include/dtoa.h new file mode 100755 index 0000000000000000000000000000000000000000..9bfb6251db831c59579b157625e8a3fc492d1e77 --- /dev/null +++ b/python_part/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_part/python/include/dynamic_annotations.h b/python_part/python/include/dynamic_annotations.h new file mode 100755 index 0000000000000000000000000000000000000000..0bd1a833c2e5a54ef951321abe83f5d693d5d39c --- /dev/null +++ b/python_part/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_part/python/include/enumobject.h b/python_part/python/include/enumobject.h new file mode 100755 index 0000000000000000000000000000000000000000..c14dbfc8c37e7c9316b9cca0a5969ee925d729d8 --- /dev/null +++ b/python_part/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_part/python/include/errcode.h b/python_part/python/include/errcode.h new file mode 100755 index 0000000000000000000000000000000000000000..b37cd261d5ec4d54ac6b8ca9fd6008e70e35859a --- /dev/null +++ b/python_part/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_part/python/include/eval.h b/python_part/python/include/eval.h new file mode 100755 index 0000000000000000000000000000000000000000..2c1c2d0549a9a40fcf054adf9b7138fa851f78ce --- /dev/null +++ b/python_part/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_part/python/include/fileobject.h b/python_part/python/include/fileobject.h new file mode 100755 index 0000000000000000000000000000000000000000..6ec2994aa859b6fbcd71d12fd283733ea1d049ab --- /dev/null +++ b/python_part/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_part/python/include/fileutils.h b/python_part/python/include/fileutils.h new file mode 100755 index 0000000000000000000000000000000000000000..359dd0ad4ead015abbdb6638e2b57dd22dfbea95 --- /dev/null +++ b/python_part/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_part/python/include/floatobject.h b/python_part/python/include/floatobject.h new file mode 100755 index 0000000000000000000000000000000000000000..f1044d64cba84d3d328d3485431f103cf2a2b3fe --- /dev/null +++ b/python_part/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_part/python/include/frameobject.h b/python_part/python/include/frameobject.h new file mode 100755 index 0000000000000000000000000000000000000000..3bad86a66f752df021975714a208088d0fba00ad --- /dev/null +++ b/python_part/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_part/python/include/funcobject.h b/python_part/python/include/funcobject.h new file mode 100755 index 0000000000000000000000000000000000000000..e563a74a15b6e182a99bdc7bb276b4a660c9f6c6 --- /dev/null +++ b/python_part/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_part/python/include/genobject.h b/python_part/python/include/genobject.h new file mode 100755 index 0000000000000000000000000000000000000000..59ede281f44f22eb29fa8083ec89902e7c414436 --- /dev/null +++ b/python_part/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_part/python/include/graminit.h b/python_part/python/include/graminit.h new file mode 100755 index 0000000000000000000000000000000000000000..d1027b7a743f2430e111751ed7a8bd484186b5cb --- /dev/null +++ b/python_part/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_part/python/include/grammar.h b/python_part/python/include/grammar.h new file mode 100755 index 0000000000000000000000000000000000000000..4b66b1e9b97451b1291fcd6eb094b60fd2019b34 --- /dev/null +++ b/python_part/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_part/python/include/import.h b/python_part/python/include/import.h new file mode 100755 index 0000000000000000000000000000000000000000..13c614933c7c2b062770cb7bfcb5ee34acc37362 --- /dev/null +++ b/python_part/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_part/python/include/internal/pycore_accu.h b/python_part/python/include/internal/pycore_accu.h new file mode 100755 index 0000000000000000000000000000000000000000..d346222e4dd0c9789f01ca1b97c96124bc01abae --- /dev/null +++ b/python_part/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_part/python/include/internal/pycore_atomic.h b/python_part/python/include/internal/pycore_atomic.h new file mode 100755 index 0000000000000000000000000000000000000000..336bc3fec27e5d9f85df21418597a9e34c15802c --- /dev/null +++ b/python_part/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_part/python/include/internal/pycore_ceval.h b/python_part/python/include/internal/pycore_ceval.h new file mode 100755 index 0000000000000000000000000000000000000000..4c1c0e2439eea450bbc969fd75a4129f0278a2ce --- /dev/null +++ b/python_part/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_part/python/include/internal/pycore_code.h b/python_part/python/include/internal/pycore_code.h new file mode 100755 index 0000000000000000000000000000000000000000..88956f109b4f79a3ac7544edbd2a7962eaf46fcc --- /dev/null +++ b/python_part/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_part/python/include/internal/pycore_condvar.h b/python_part/python/include/internal/pycore_condvar.h new file mode 100755 index 0000000000000000000000000000000000000000..8b89d709510a3382a94e919f4d8ee56f7f1c21a0 --- /dev/null +++ b/python_part/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_part/python/include/internal/pycore_context.h b/python_part/python/include/internal/pycore_context.h new file mode 100755 index 0000000000000000000000000000000000000000..5e1ba0d0393f4a690e0e2857ea13222fe777028d --- /dev/null +++ b/python_part/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_part/python/include/internal/pycore_fileutils.h b/python_part/python/include/internal/pycore_fileutils.h new file mode 100755 index 0000000000000000000000000000000000000000..bbee58617fd05e45ddc9adf146cf3ebb903e4551 --- /dev/null +++ b/python_part/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_part/python/include/internal/pycore_getopt.h b/python_part/python/include/internal/pycore_getopt.h new file mode 100755 index 0000000000000000000000000000000000000000..7f0dd13ae577f78491f19b7e8fa3ac8c5042bb11 --- /dev/null +++ b/python_part/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_part/python/include/internal/pycore_gil.h b/python_part/python/include/internal/pycore_gil.h new file mode 100755 index 0000000000000000000000000000000000000000..7de316397b15e8ac9bbbc5ddb280bff19519f786 --- /dev/null +++ b/python_part/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_part/python/include/internal/pycore_hamt.h b/python_part/python/include/internal/pycore_hamt.h new file mode 100755 index 0000000000000000000000000000000000000000..e65aef5e21a9548493a1e797881e42bd72f8382a --- /dev/null +++ b/python_part/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_part/python/include/internal/pycore_initconfig.h b/python_part/python/include/internal/pycore_initconfig.h new file mode 100755 index 0000000000000000000000000000000000000000..40831c44b2fa674be62fe60eafbe16b842eb1f34 --- /dev/null +++ b/python_part/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_part/python/include/internal/pycore_object.h b/python_part/python/include/internal/pycore_object.h new file mode 100755 index 0000000000000000000000000000000000000000..7418c6936b8f0b8eda6cef18b65e11aa08de450a --- /dev/null +++ b/python_part/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_part/python/include/internal/pycore_pathconfig.h b/python_part/python/include/internal/pycore_pathconfig.h new file mode 100755 index 0000000000000000000000000000000000000000..ce75ccee835a204230fe92f93cae9e4a5761e1a7 --- /dev/null +++ b/python_part/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_part/python/include/internal/pycore_pyerrors.h b/python_part/python/include/internal/pycore_pyerrors.h new file mode 100755 index 0000000000000000000000000000000000000000..23327ef78397430e841d329f457978116bb3e7c8 --- /dev/null +++ b/python_part/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_part/python/include/internal/pycore_pyhash.h b/python_part/python/include/internal/pycore_pyhash.h new file mode 100755 index 0000000000000000000000000000000000000000..a229f8d8b7f0a2ab0bf9120fcc301cc5c74594c8 --- /dev/null +++ b/python_part/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_part/python/include/internal/pycore_pylifecycle.h b/python_part/python/include/internal/pycore_pylifecycle.h new file mode 100755 index 0000000000000000000000000000000000000000..c237b1da894833355e81b015ee0c9b9645c3bb8c --- /dev/null +++ b/python_part/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_part/python/include/internal/pycore_pymem.h b/python_part/python/include/internal/pycore_pymem.h new file mode 100755 index 0000000000000000000000000000000000000000..47d092f3e53ff3a511365027f140edc4ec1c55a7 --- /dev/null +++ b/python_part/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_part/python/include/internal/pycore_pystate.h b/python_part/python/include/internal/pycore_pystate.h new file mode 100755 index 0000000000000000000000000000000000000000..18105335363a45d04c86a758c81301e57e3e6ee5 --- /dev/null +++ b/python_part/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_part/python/include/internal/pycore_traceback.h b/python_part/python/include/internal/pycore_traceback.h new file mode 100755 index 0000000000000000000000000000000000000000..bf4d7fe5851f96fa58170068ba23955926fcc2a4 --- /dev/null +++ b/python_part/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_part/python/include/internal/pycore_tupleobject.h b/python_part/python/include/internal/pycore_tupleobject.h new file mode 100755 index 0000000000000000000000000000000000000000..9fcfc5c6ec71960ca97387469b7c001ec4c89293 --- /dev/null +++ b/python_part/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_part/python/include/internal/pycore_warnings.h b/python_part/python/include/internal/pycore_warnings.h new file mode 100755 index 0000000000000000000000000000000000000000..73e5350aff1451e01accdab1d63559d58276f2b7 --- /dev/null +++ b/python_part/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_part/python/include/interpreteridobject.h b/python_part/python/include/interpreteridobject.h new file mode 100755 index 0000000000000000000000000000000000000000..e744fcdc9ff1899c825ac44009a59002f3990178 --- /dev/null +++ b/python_part/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_part/python/include/intrcheck.h b/python_part/python/include/intrcheck.h new file mode 100755 index 0000000000000000000000000000000000000000..e5bf5a834e44c8edda0158255214abed8503a2a9 --- /dev/null +++ b/python_part/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_part/python/include/iterobject.h b/python_part/python/include/iterobject.h new file mode 100755 index 0000000000000000000000000000000000000000..f61726f1f7f83af90a53ef1488b7dad385444698 --- /dev/null +++ b/python_part/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_part/python/include/listobject.h b/python_part/python/include/listobject.h new file mode 100755 index 0000000000000000000000000000000000000000..6057279d51c3a482510e0a69ad7f99103344fe8c --- /dev/null +++ b/python_part/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_part/python/include/longintrepr.h b/python_part/python/include/longintrepr.h new file mode 100755 index 0000000000000000000000000000000000000000..ff4155f9656defa2bc7623ddb4ecee6f45564dfc --- /dev/null +++ b/python_part/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_part/python/include/longobject.h b/python_part/python/include/longobject.h new file mode 100755 index 0000000000000000000000000000000000000000..1e7a58d994b8a486e23a4f71cab0ff90d5560d2f --- /dev/null +++ b/python_part/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_part/python/include/marshal.h b/python_part/python/include/marshal.h new file mode 100755 index 0000000000000000000000000000000000000000..09d9337e57b0aa3ca18ba4a64bc360f8661ec080 --- /dev/null +++ b/python_part/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_part/python/include/memoryobject.h b/python_part/python/include/memoryobject.h new file mode 100755 index 0000000000000000000000000000000000000000..990a716f220399a11af26a78c15682d9e3ca358b --- /dev/null +++ b/python_part/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_part/python/include/methodobject.h b/python_part/python/include/methodobject.h new file mode 100755 index 0000000000000000000000000000000000000000..ba3b8878a6c4191aab079c5ed5a014ed3bc68dd5 --- /dev/null +++ b/python_part/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_part/python/include/modsupport.h b/python_part/python/include/modsupport.h new file mode 100755 index 0000000000000000000000000000000000000000..f90ede4831e32ba0bf17f9c7b6716afdb3cb6531 --- /dev/null +++ b/python_part/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_part/python/include/moduleobject.h b/python_part/python/include/moduleobject.h new file mode 100755 index 0000000000000000000000000000000000000000..e246fd2faf9184805a48f93d346a960ed9726868 --- /dev/null +++ b/python_part/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_part/python/include/namespaceobject.h b/python_part/python/include/namespaceobject.h new file mode 100755 index 0000000000000000000000000000000000000000..0c8d95c0f137c689c1e6cf7ffa6d5b91cc255641 --- /dev/null +++ b/python_part/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_part/python/include/node.h b/python_part/python/include/node.h new file mode 100755 index 0000000000000000000000000000000000000000..2b39074097387335f3675271048b2f3783a7c7f0 --- /dev/null +++ b/python_part/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_part/python/include/object.h b/python_part/python/include/object.h new file mode 100755 index 0000000000000000000000000000000000000000..5558f65687adc05e00edcad040a0d01b0d777444 --- /dev/null +++ b/python_part/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_part/python/include/objimpl.h b/python_part/python/include/objimpl.h new file mode 100755 index 0000000000000000000000000000000000000000..2337d8a56c774e31b90077e97657edbac97587dc --- /dev/null +++ b/python_part/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_part/python/include/odictobject.h b/python_part/python/include/odictobject.h new file mode 100755 index 0000000000000000000000000000000000000000..35aff8a29a6e34f2c3262bb9a8d44bd1b449f752 --- /dev/null +++ b/python_part/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_part/python/include/opcode.h b/python_part/python/include/opcode.h new file mode 100755 index 0000000000000000000000000000000000000000..2a29e978857035a275055bf54d30149de98c616b --- /dev/null +++ b/python_part/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_part/python/include/osdefs.h b/python_part/python/include/osdefs.h new file mode 100755 index 0000000000000000000000000000000000000000..3243944a1483e95904b4d7d75d0e152ac00824e5 --- /dev/null +++ b/python_part/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_part/python/include/osmodule.h b/python_part/python/include/osmodule.h new file mode 100755 index 0000000000000000000000000000000000000000..9095c2fdd3d638140db129937d29830286941819 --- /dev/null +++ b/python_part/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_part/python/include/parsetok.h b/python_part/python/include/parsetok.h new file mode 100755 index 0000000000000000000000000000000000000000..935d733e90a5afed7fadbda7596337b169d5fd50 --- /dev/null +++ b/python_part/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_part/python/include/patchlevel.h b/python_part/python/include/patchlevel.h new file mode 100755 index 0000000000000000000000000000000000000000..d23d5afcd8d8e3820a6a8a46a72f474b73d389d3 --- /dev/null +++ b/python_part/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_part/python/include/picklebufobject.h b/python_part/python/include/picklebufobject.h new file mode 100755 index 0000000000000000000000000000000000000000..f07e900bf26dacf2dfcc797495b245fa03df50be --- /dev/null +++ b/python_part/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_part/python/include/py_curses.h b/python_part/python/include/py_curses.h new file mode 100755 index 0000000000000000000000000000000000000000..2702b37ea7cfe95d76be65a4fb0dee3a524eccf8 --- /dev/null +++ b/python_part/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_part/python/include/pyarena.h b/python_part/python/include/pyarena.h new file mode 100755 index 0000000000000000000000000000000000000000..db3ad0188fe1cd9f685d7c27d3869adae912d574 --- /dev/null +++ b/python_part/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_part/python/include/pycapsule.h b/python_part/python/include/pycapsule.h new file mode 100755 index 0000000000000000000000000000000000000000..d9ecda7a4b6e4a1f26500770e79b7996425d3832 --- /dev/null +++ b/python_part/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_part/python/include/pyctype.h b/python_part/python/include/pyctype.h new file mode 100755 index 0000000000000000000000000000000000000000..729d93275e6c5365fb26fd521b1ff58de22b5fdb --- /dev/null +++ b/python_part/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_part/python/include/pydebug.h b/python_part/python/include/pydebug.h new file mode 100755 index 0000000000000000000000000000000000000000..bd4aafe3b49f83a3dc5d6e3c56b3425220c5c0b7 --- /dev/null +++ b/python_part/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_part/python/include/pydtrace.d b/python_part/python/include/pydtrace.d new file mode 100755 index 0000000000000000000000000000000000000000..5e6a626b01b82f669d685668d4c5ffa3ff474111 --- /dev/null +++ b/python_part/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_part/python/include/pydtrace.h b/python_part/python/include/pydtrace.h new file mode 100755 index 0000000000000000000000000000000000000000..75f8e7f70979c5266635dcf476605421b6a0fad9 --- /dev/null +++ b/python_part/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_part/python/include/pyerrors.h b/python_part/python/include/pyerrors.h new file mode 100755 index 0000000000000000000000000000000000000000..5125a51ec1aa17e9b347eea97dedd54e03462ef6 --- /dev/null +++ b/python_part/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_part/python/include/pyexpat.h b/python_part/python/include/pyexpat.h new file mode 100755 index 0000000000000000000000000000000000000000..07020b5dc964cb3abeeb7bd14131dce55acc737a --- /dev/null +++ b/python_part/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_part/python/include/pyfpe.h b/python_part/python/include/pyfpe.h new file mode 100755 index 0000000000000000000000000000000000000000..5a99e3979311f8118066c9325933ac74e7a48233 --- /dev/null +++ b/python_part/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_part/python/include/pyhash.h b/python_part/python/include/pyhash.h new file mode 100755 index 0000000000000000000000000000000000000000..dbcc9744be35a7bba2b760840db4312d5b8cc08a --- /dev/null +++ b/python_part/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_part/python/include/pylifecycle.h b/python_part/python/include/pylifecycle.h new file mode 100755 index 0000000000000000000000000000000000000000..c5368b3c5edaa08c7db2ca2f30d291127e1839d8 --- /dev/null +++ b/python_part/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_part/python/include/pymacconfig.h b/python_part/python/include/pymacconfig.h new file mode 100755 index 0000000000000000000000000000000000000000..9dde11bd58e2171be78ecf4d3423b1b231ac17ec --- /dev/null +++ b/python_part/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_part/python/include/pymacro.h b/python_part/python/include/pymacro.h new file mode 100755 index 0000000000000000000000000000000000000000..495c2c25c90866de20e8607c7e7b77bb438bf503 --- /dev/null +++ b/python_part/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_part/python/include/pymath.h b/python_part/python/include/pymath.h new file mode 100755 index 0000000000000000000000000000000000000000..6cf69f98acf93340a6bc45bee250d89c1d9d436d --- /dev/null +++ b/python_part/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_part/python/include/pymem.h b/python_part/python/include/pymem.h new file mode 100755 index 0000000000000000000000000000000000000000..07b380aa6e7faaf3cc2c9de4ed15375cea19c82f --- /dev/null +++ b/python_part/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_part/python/include/pyport.h b/python_part/python/include/pyport.h new file mode 100755 index 0000000000000000000000000000000000000000..71f5794ded72e1179bef5952a6b4a86e6fefff98 --- /dev/null +++ b/python_part/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_part/python/include/pystate.h b/python_part/python/include/pystate.h new file mode 100755 index 0000000000000000000000000000000000000000..4c25e3f7ef84b5d8c3f22ef4b4f5cc5db7d1d357 --- /dev/null +++ b/python_part/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_part/python/include/pystrcmp.h b/python_part/python/include/pystrcmp.h new file mode 100755 index 0000000000000000000000000000000000000000..edb12397e3cbcc761a5ba28221215a62193a48ba --- /dev/null +++ b/python_part/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_part/python/include/pystrhex.h b/python_part/python/include/pystrhex.h new file mode 100755 index 0000000000000000000000000000000000000000..a4f36305bac69bd84684a5ef4d26d1e091e24232 --- /dev/null +++ b/python_part/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_part/python/include/pystrtod.h b/python_part/python/include/pystrtod.h new file mode 100755 index 0000000000000000000000000000000000000000..c1e84de6fe54287cd8dcdfa6147f8b1e31cc3400 --- /dev/null +++ b/python_part/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_part/python/include/pythonrun.h b/python_part/python/include/pythonrun.h new file mode 100755 index 0000000000000000000000000000000000000000..46091e09216330bb39b8bb68a8d718dea40cd33f --- /dev/null +++ b/python_part/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_part/python/include/pythread.h b/python_part/python/include/pythread.h new file mode 100755 index 0000000000000000000000000000000000000000..f22e8c42c502777969e6516c9257341b2b50e4d7 --- /dev/null +++ b/python_part/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_part/python/include/pytime.h b/python_part/python/include/pytime.h new file mode 100755 index 0000000000000000000000000000000000000000..bdda1da2e6b8f2ec6bce29688a67f8137f7d9208 --- /dev/null +++ b/python_part/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_part/python/include/rangeobject.h b/python_part/python/include/rangeobject.h new file mode 100755 index 0000000000000000000000000000000000000000..7e4dc28894b042097c22387ad31dfe80ad8917f8 --- /dev/null +++ b/python_part/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_part/python/include/setobject.h b/python_part/python/include/setobject.h new file mode 100755 index 0000000000000000000000000000000000000000..fc0ea83925f92f2e51a6f61a1e8060ee928f5865 --- /dev/null +++ b/python_part/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_part/python/include/sliceobject.h b/python_part/python/include/sliceobject.h new file mode 100755 index 0000000000000000000000000000000000000000..aae6f3cc7945e1774d10f58e332dab4fd475d592 --- /dev/null +++ b/python_part/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_part/python/include/structmember.h b/python_part/python/include/structmember.h new file mode 100755 index 0000000000000000000000000000000000000000..b54f7081f458dd9c33a524874b4b3e90c3bbf954 --- /dev/null +++ b/python_part/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_part/python/include/structseq.h b/python_part/python/include/structseq.h new file mode 100755 index 0000000000000000000000000000000000000000..e5e5d5c5735e9d5dc79d3417c09be5a1e7556d3f --- /dev/null +++ b/python_part/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_part/python/include/symtable.h b/python_part/python/include/symtable.h new file mode 100755 index 0000000000000000000000000000000000000000..5dcfa7e2c2bb68e95850975da5fbf65566fcc604 --- /dev/null +++ b/python_part/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_part/python/include/sysmodule.h b/python_part/python/include/sysmodule.h new file mode 100755 index 0000000000000000000000000000000000000000..670e5d283f770197b30bb691162195a1ffea9709 --- /dev/null +++ b/python_part/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_part/python/include/token.h b/python_part/python/include/token.h new file mode 100755 index 0000000000000000000000000000000000000000..e08708baf196e8b1a63bb841f4c1ef8137aa9f4f --- /dev/null +++ b/python_part/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_part/python/include/traceback.h b/python_part/python/include/traceback.h new file mode 100755 index 0000000000000000000000000000000000000000..b451927fafa3a85fb86510c56dffdd0845a43d99 --- /dev/null +++ b/python_part/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_part/python/include/tracemalloc.h b/python_part/python/include/tracemalloc.h new file mode 100755 index 0000000000000000000000000000000000000000..bd14217c199c3cb212aa8253d1c32c0e53325b40 --- /dev/null +++ b/python_part/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_part/python/include/tupleobject.h b/python_part/python/include/tupleobject.h new file mode 100755 index 0000000000000000000000000000000000000000..590902de9d0215c35f5455013c729e61cfaddafa --- /dev/null +++ b/python_part/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_part/python/include/typeslots.h b/python_part/python/include/typeslots.h new file mode 100755 index 0000000000000000000000000000000000000000..0ce6a377dcfbd692e5b2204496a5c8dd8d7cc8f2 --- /dev/null +++ b/python_part/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_part/python/include/ucnhash.h b/python_part/python/include/ucnhash.h new file mode 100755 index 0000000000000000000000000000000000000000..45362e997dfa118f30d2c5bb4406105f744ce53b --- /dev/null +++ b/python_part/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_part/python/include/unicodeobject.h b/python_part/python/include/unicodeobject.h new file mode 100755 index 0000000000000000000000000000000000000000..97d8cd12f6de5494a1c32140ade1857c47c89020 --- /dev/null +++ b/python_part/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_part/python/include/warnings.h b/python_part/python/include/warnings.h new file mode 100755 index 0000000000000000000000000000000000000000..a675bb5dfcb9f5009c70b9e7fe3ecf6e20e76866 --- /dev/null +++ b/python_part/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_part/python/include/weakrefobject.h b/python_part/python/include/weakrefobject.h new file mode 100755 index 0000000000000000000000000000000000000000..17051568f3a6e9880a7ceae50b85088f179edf37 --- /dev/null +++ b/python_part/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_part/python/pyconfig.h b/python_part/python/pyconfig.h new file mode 100755 index 0000000000000000000000000000000000000000..9d53ac6396b2f329316a68245b6c9c0d89e53618 --- /dev/null +++ b/python_part/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*/ +